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))
    }
}
但是我遇到了两个错误,主要是这个错误:
错误:类型不匹配:预期
Rustmark<P, R>,找到Rustmark<parser::DefaultParser, renderers::html::HTMLRenderer>(预期类型参数,找到结构parser::DefaultParser)[E0308]
还有一些像这样的终身错误:
错误:由于需求冲突,无法推断自动强制的适当寿命
帮助:考虑使用显式的生命周期参数,如下所示:
fn parse<'a>(&'a self, input: &'a str) -> &str
我尝试了多次调整以使其正常工作,但似乎都没有一个使编译器安心。所以我想知道这是否是正确的方法,以及如何使它起作用。
第一个错误:您创建一个Rustmark具有parsertype DefaultParser的字段renderer和type的对象HTMLRenderer,但是该函数应该返回Rustmark <P, R>。通常,P不是type,DefaultParser而R不是type HTMLRenderer,因此它将永远不会编译。如果要使用正确类型的默认值,一个好的解决方案是绑定P并R实现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方法内部消失(String您render可能在内部方法中分配)。编译器告诉您它不知道该引用指向的对象的生存期,因此它不能保证该引用是有效的。您可以指定一个生命周期参数,但是在您的情况下,最好的解决方案是返回String对象本身,而不是引用。