当调用一个不带 trait 的默认实现时self,为什么需要注释一个实现类型?
下面是一个最小的、可重复的示例(playground):
mod builder {
pub trait Builder: Sized {
fn new() -> Simple {
Simple
}
}
pub struct Simple;
impl Builder for Simple {}
}
pub fn main() {
let _ = builder::Builder::new();
/* Working version */
// use builder::Builder;
// let _ = builder::Simple::new();
}
Run Code Online (Sandbox Code Playgroud)
这使:
error[E0283]: type annotations needed
--> src/main.rs:14:13
|
3 | fn new() -> Simple {
| ------------------ required by `builder::Builder::new`
...
14 | let _ = builder::Builder::new();
| ^^^^^^^^^^^^^^^^^^^^^ cannot infer type
|
= note: cannot satisfy `_: builder::Builder`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0283`.
error: could not compile `playground`.
To learn more, run the command again with --verbose.
Run Code Online (Sandbox Code Playgroud)
的编译器解释E0283没有提到默认实现,我同意这是有道理的。但是对于默认实现,为什么需要类型?
这不仅是一个默认实现,而且是一个非常特殊的情况,其中这个默认实现在其参数、结果和正文中甚至没有提到Self/ self。
我发现更容易理解的规则是,在任何情况下,每次我们使用 trait 时都需要一个类型,而不是« 除非默认实现在其参数、结果和正文中甚至没有提到Self/self。
对于这个非常具体的用例,您不想在调用所需函数时显式命名类型,我建议使用免费函数。
mod builder {
// ...
pub fn make_default() -> Simple {
Simple
}
// ...
}
pub fn main() {
let _ = builder::make_default();
}
Run Code Online (Sandbox Code Playgroud)