问题描述
当调用一个不带 self
的 trait 的默认实现时,为什么它需要一个被注释的实现类型?
When calling a default implementation on a trait which does not take self
, why does it neeed an implementing type to be annotated?
最小的、可重现的示例如下(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();
}
给出:
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.
E0283
的编译器解释没有提到默认实现,我同意这是有道理的.但是对于默认实现,为什么需要类型?
The compiler explanation for E0283
does not mention a default implementation, which I agree it makes sense. But for default implementations, why is a type required?
推荐答案
Rust 中提供的方法与 Java 中的 static
方法不同.即使没有参数和默认实现的函数也可以被实现者覆盖.考虑添加另一种实现 Builder
但覆盖 new
函数的类型:
Provided methods in Rust are not like static
methods in Java. Even a function with no arguments and a default implementation can be overridden by implementors. Consider adding another type that implements Builder
but overrides the new
function:
struct Noisy {}
impl builder::Builder for Noisy {
fn new() -> builder::Simple {
println!("Ahahahah I'm creating a Simple!!!11!");
builder::Simple
}
}
fn main() {
// wait, should this call builder::Simple::new() or Noisy::new()?
let _ = builder::Builder::new();
}
如果您想要始终具有相同行为的 Java static
函数的效果,您应该使用自由函数,如 prog-fh 的回答 也提出了建议.
If you want the effect of a Java static
function that always has the same behavior, you should use a free function, as prog-fh's answer also suggests.
这篇关于为什么编译器需要一个 trait 的实现来调用默认的自由函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!