Generics Error: expected type parameter, found struct
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))
}
}
但是我遇到了一些错误,主要是这个:
error: mismatched types:
expected Rustmark<P, R>
,
found Rustmark<parser::DefaultParser, renderers::html::HTMLRenderer>
(expected type parameter,
found struct parser::DefaultParser
) [E0308]
还有几个这样的终生错误:
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
我尝试了多次调整以使其工作,但其中 none 似乎让编译器安心了。所以我想知道这是否是正确的方法,以及我可以做些什么来让它发挥作用。
第一个错误:您使用类型 DefaultParser
的字段 parser
和类型 HTMLRenderer
的字段 renderer
创建了一个 Rustmark
对象,但是函数预计 return Rustmark <P, R>
。一般来说,P 不是 DefaultParser
类型,R 也不是 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(),
}
}
}
第二个错误:主要问题是你 return 引用了可能会在 render
方法中消失的东西(你在内部 render
中分配的 String
=]方法可能)。编译器告诉您它不知道该引用指向的对象的生命周期,因此它不能保证该引用有效。您可以指定生命周期参数,但在您的情况下,最好的解决方案可能是 return String
对象本身,而不是引用。
根据 Andrea P 的回答,我在 std 中查找了 default
特征。定义如下:
pub trait Default {
fn default() -> Self;
}
我最后做的不是使用 default
特性,而是在我的 MarkParser
和 MarkRenderer
这样的特征:
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
特征添加到 RustMark 的 impl
。
impl <P: MarkParser, R: MarkRenderer> Rustmark <P, R> {
而不是
impl <P: MarkParser + Default, R: MarkRenderer + Default> Rustmark <P, R> {
非常感谢 Andrea P 为我指明了正确的方向。
我开始了一个新项目,我希望尽可能地模块化,我的意思是我希望将来能够用其他部分替换某些部分。这似乎是 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))
}
}
但是我遇到了一些错误,主要是这个:
error: mismatched types: expected
Rustmark<P, R>
, foundRustmark<parser::DefaultParser, renderers::html::HTMLRenderer>
(expected type parameter, found structparser::DefaultParser
) [E0308]
还有几个这样的终生错误:
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
我尝试了多次调整以使其工作,但其中 none 似乎让编译器安心了。所以我想知道这是否是正确的方法,以及我可以做些什么来让它发挥作用。
第一个错误:您使用类型 DefaultParser
的字段 parser
和类型 HTMLRenderer
的字段 renderer
创建了一个 Rustmark
对象,但是函数预计 return Rustmark <P, R>
。一般来说,P 不是 DefaultParser
类型,R 也不是 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(),
}
}
}
第二个错误:主要问题是你 return 引用了可能会在 render
方法中消失的东西(你在内部 render
中分配的 String
=]方法可能)。编译器告诉您它不知道该引用指向的对象的生命周期,因此它不能保证该引用有效。您可以指定生命周期参数,但在您的情况下,最好的解决方案可能是 return String
对象本身,而不是引用。
根据 Andrea P 的回答,我在 std 中查找了 default
特征。定义如下:
pub trait Default {
fn default() -> Self;
}
我最后做的不是使用 default
特性,而是在我的 MarkParser
和 MarkRenderer
这样的特征:
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
特征添加到 RustMark 的 impl
。
impl <P: MarkParser, R: MarkRenderer> Rustmark <P, R> {
而不是
impl <P: MarkParser + Default, R: MarkRenderer + Default> Rustmark <P, R> {
非常感谢 Andrea P 为我指明了正确的方向。