繁体   English   中英

泛型错误:期望的类型参数,找到结构

[英]Generics Error: expected type parameter, found struct

我开始了一个新项目,我希望尽可能模块化,我的意思是我希望将来可以替换其他部分。 这似乎是一个完美的使用traits ,在现阶段,我有这样的代码:

mod parser;
mod renderer;
mod renderers;

use parser::MarkParser;
use renderer::MarkRenderer;

struct Rustmark <P: MarkParser, R: MarkRenderer> {
    parser: P,
    renderer: R,
}


impl <P: MarkParser, R: MarkRenderer> Rustmark <P, R> {
    fn new() -> Rustmark <P, R> {
        Rustmark {
            parser: parser::DefaultParser::new(),
            renderer: renderers::HTMLRenderer::new(),
        }
    }

    fn render(&self, input: &str) -> &str {
        self.renderer.render(self.parser.parse(input))
    }
}

但是我得到了一些错误,主要是这个错误:

错误:类型不匹配:预期Rustmark<P, R> ,找到Rustmark<parser::DefaultParser, renderers::html::HTMLRenderer> (期望的类型参数,找到struct parser::DefaultParser )[E0308]

还有一些像这样的生命周期错误:

错误:由于需求冲突,无法推断自动强制的适当生命周期

help:考虑使用如下所示的显式生命周期参数: fn parse<'a>(&'a self, input: &'a str) -> &str

我尝试了多次调整以使其工作,但它们似乎都没有安抚编译器。 所以我想知道这是否是正确的方法以及我能做些什么才能使它发挥作用。

第一个错误:使用DefaultParser类型的字段parserHTMLRenderer类型的字段renderer创建Rustmark对象,但该函数应返回Rustmark <P, R> 通常,P不是DefaultParser类型,R不是HTMLRenderer类型,因此它永远不会编译。 如果您想要具有正确类型的默认值,那么一个好的解决方案是绑定PR以实现Default trait ,这样:

use std::default:Default;

impl <P: MarkParser + Default, R: MarkRenderer + Default> Rustmark <P, R> {
    fn new() -> Rustmark <P, R> {
        Rustmark {
            parser: P::default(),
            renderer: R:default(),
        }
    }
}

第二个错误:主要问题是你返回一个可能会在render方法中死掉的引用(你可能在内部render方法中分配的String )。 编译器告诉您它不知道该引用指向的对象的生命周期,因此无法保证该引用有效。 您可以指定一个生命周期参数,但在您的情况下,最好的解决方案可能是返回String对象本身,而不是引用。

根据Andrea P的回答,我在std中查找了default特征。 其定义如下:

pub trait Default {
    fn default() -> Self;
}

我最终做的不是使用default特征,而是在我的MarkParserMarkRenderer特征中添加一个构造函数 new ,如下所示:

pub trait MarkParser {
    fn new() -> Self;
    fn parse(&self, input: &str) -> &str;
}

我不知道的关键部分是Self关键字,这样我就可以编写我的实现:

impl <P: MarkParser, R: MarkRenderer> Rustmark <P, R> {
    fn new() -> Rustmark <P, R> {
        Rustmark {
            parser: P::new(),
            renderer: R::new(),
        }
    }

    fn render(&self, input: &str) -> &str {
        self.renderer.render(self.parser.parse(input))
    }
}

这也正是同样的事情,执行Default特质,除了我可以使用new的,而不是default ,我更喜欢我没有到添加Default性状的impl RustMark的。

impl <P: MarkParser, R: MarkRenderer> Rustmark <P, R> {

代替

impl <P: MarkParser + Default, R: MarkRenderer + Default> Rustmark <P, R> {

非常感谢Andrea P指出我正确的方向。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM