泛型错误:期望的类型参数,找到结构 [英] Generics Error: expected type parameter, found struct
问题描述
我开始了一个新项目,我希望尽可能模块化,我的意思是我希望将来能够替换其他部分。这似乎是 traits
的完美用法,目前我有这样的代码:
mod解析器;
mod渲染器;
mod渲染器;
使用解析器:: MarkParser;
使用renderer :: MarkRenderer;
struct Rustmark< P:MarkParser,R:MarkRenderer> {
解析器:P,
渲染器:R,
}
impl< P:MarkParser,R:MarkRenderer> Rustmark< P,R> {
fn new() - > Rustmark< P,R> {
Rustmark {
parser:parser :: DefaultParser :: new(),
renderer:renderers :: HTMLRenderer :: new(),
}
}
fn渲染(& self,input:& str) - > & str {
self.renderer.render(self.parser.parse(input))
}
}
但是我遇到了一些错误,主要是这个错误:
错误:不匹配的类型:
预期Rustmark< P,R>
,
找到Rustmark< parser :: DefaultParser ,renderers :: html :: HTMLRenderer>
(预期的类型参数,
found structparser :: DefaultParser
)[ E0308]
还有一些像这样的终生错误:
错误:由于需求冲突而无法推断自动强制的适当生命周期。
help:考虑使用显式的生命期参数,如下所示:
fn parse<'a>(&'a self,input:&'a str) - > & str
我已经尝试过多次调整以使其正常工作,但它们似乎没有任何安抚编译器。所以我想知道这是否是正确的方法,并且我可以做些什么才能使其正常工作。
第一个错误:您使用类型 DefaultParser
的字段解析器
创建 Rustmark
>和类型 HTMLRenderer
的字段渲染器
,但该函数预期会返回 Rustmark< ; P,R>
。一般来说P不是 DefaultParser
类型,R不是 HTMLRenderer
类型,所以它永远不会编译。如果你想拥有正确类型的默认值,一个好的解决方案是限制 P
和 R
来实现 Default
trait
,这样: 使用std :: default:Default;
impl< P:MarkParser +默认,R:MarkRenderer +默认> Rustmark< P,R> {
fn new() - > Rustmark< P,R> {
Rustmark {
parser:P :: default(),
渲染器:R:default(),
}
}
}
第二个错误:主要问题是您返回了一些可能会死于 render
方法(可能你在内部的 render
方法中分配了 String
)。编译器告诉你它不知道该引用指向的对象的生命周期,因此它不能保证该引用是有效的。您可以指定一个生命周期参数,但在您的情况下,最好的解决方案是返回 String
对象本身,而不是引用。
I started a new project, where I want to be as modular as possible, by that I mean that I would like to be able to replace some parts with others in the future. This seems to be a perfect use for traits
, at the moment I have this code:
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))
}
}
But I get a couple of errors, mainly this one:
error: mismatched types: expected
Rustmark<P, R>
, foundRustmark<parser::DefaultParser, renderers::html::HTMLRenderer>
(expected type parameter, found structparser::DefaultParser
) [E0308]
And a couple of lifetime errors like this one:
error: cannot infer an appropriate lifetime for automatic coercion due to conflicting requirements
help: consider using an explicit lifetime parameter as shown:
fn parse<'a>(&'a self, input: &'a str) -> &str
I have tried multiple tweaks to make it work, but none of them seemed to appease the compiler. So I wanted to know if this is the right approach and what I could do to to make it work.
First error: you create a Rustmark
object with the field parser
of type DefaultParser
and the field renderer
of type HTMLRenderer
, but the function is expected to return Rustmark <P, R>
. In general P is not of type DefaultParser
and R is not of type HTMLRenderer
, so it will never compile. A good solution if you want have default values of the right type is to bound P
and R
to implement the Default
trait
, this way:
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(),
}
}
}
Second error: that main problem is that you return a reference of something that probably will die inside the render
method (the String
you allocate in the inner render
method probably). The compiler is telling you that it doesn't know the lifetime of the object that is pointed by that reference, so it cannot guarantee that the reference is valid. You can specify a lifetime parameter but in your case probably the best solution is to return the String
object itself, not a reference.
这篇关于泛型错误:期望的类型参数,找到结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!