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

Mat*_*vid 5 generics traits rust

我开始了一个新项目,我希望在其中尽可能地模块化,这意味着我希望将来能够将某些零件替换为其他零件。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))
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我遇到了两个错误,主要是这个错误:

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

还有一些像这样的终身错误:

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

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

我尝试了多次调整以使其正常工作,但似乎都没有一个使编译器安心。所以我想知道这是否是正确的方法,以及如何使它起作用。

eul*_*isk 5

第一个错误:您创建一个Rustmark具有parsertype DefaultParser的字段renderer和type的对象HTMLRenderer,但是该函数应该返回Rustmark <P, R>。通常,P不是type,DefaultParser而R不是type 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(),
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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