Types 为什么编译器需要trait的实现来调用默认的自由函数?

Types 为什么编译器需要trait的实现来调用默认的自由函数?,types,rust,traits,Types,Rust,Traits,当调用一个特性上的默认实现而该特性不采用self,为什么它需要一个实现类型来进行注释 A如下(): modbuilder{ 酒吧特征生成器:大小{ fn new()->Simple{ 简单的 } } pub结构简单; 简单{}的impl生成器 } pub fn main(){ 让uz=builder::builder::new(); /*工作版本*/ //使用builder::builder; //让uz=builder::Simple::new(); } 其中: error[E0283]:

当调用一个特性上的默认实现而该特性不采用
self
,为什么它需要一个实现类型来进行注释

A如下():

modbuilder{
酒吧特征生成器:大小{
fn new()->Simple{
简单的
}
}
pub结构简单;
简单{}的impl生成器
}
pub fn main(){
让uz=builder::builder::new();
/*工作版本*/
//使用builder::builder;
//让uz=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
的编译器解释没有提到默认实现,我同意这是有意义的。但是对于默认实现,为什么需要一个类型呢?

这不仅是默认实现,而且是非常特殊的情况,在这种情况下,默认实现在其参数、结果和主体中甚至没有提到
Self
/
Self

我发现更容易理解的规则是,每次我们使用trait时都需要一个类型,而不是«除非默认实现在其参数、结果和主体中甚至没有提到
Self
/
Self

对于这个非常特殊的用例,在调用所需函数时不希望显式命名类型,我建议使用自由函数

modbuilder{
// ...
pub fn make_default()->Simple{
简单的
}
// ...
}
pub fn main(){
让u=builder::make_default();
}
这不仅是一个默认实现,而且是一个非常特殊的情况,在这种情况下,默认实现在其参数、结果和正文中甚至没有提到
Self
/
Self

我发现更容易理解的规则是,每次我们使用trait时都需要一个类型,而不是«除非默认实现在其参数、结果和主体中甚至没有提到
Self
/
Self

对于这个非常特殊的用例,在调用所需函数时不希望显式命名类型,我建议使用自由函数

modbuilder{
// ...
pub fn make_default()->Simple{
简单的
}
// ...
}
pub fn main(){
让u=builder::make_default();
}

Rust中提供的方法与Java中的
静态方法不同。即使是没有参数和默认实现的函数也可以被实现者覆盖。考虑添加另一种实现代码< > Builder < /C>的类型,但是重写<代码>新< /Cuff>函数:

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
静态
函数始终具有相同的行为,您应该使用自由函数,正如所建议的那样。

Rust中提供的方法与Java中的
静态
方法不同。即使是没有参数和默认实现的函数也可以被实现者覆盖。考虑添加另一种实现代码< > Builder < /C>的类型,但是重写<代码>新< /Cuff>函数:

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
静态
函数始终具有相同行为的效果,您应该使用免费函数,正如建议的那样。

谢谢。这实际上与我的项目中的内容相似。然而,它确实破坏了API(也打破了将
新的
作为一种方法的惯例)。所以我只是想知道,如果没有必要,为什么编译器必须强制执行它。@malinator我会发现java语言正好相反,即所有东西都必须在一个类中,即使不需要它,从而增加了独立软件块之间的耦合。«
new
作为一种方法»对于一个类型,是的,但不一定对于返回值的所有内容。谢谢。这实际上与我的项目中的内容相似。然而,它确实破坏了API(也打破了将
新的
作为一种方法的惯例)。所以我只是想知道,如果没有必要,为什么编译器必须强制执行它。@malinator我会发现java语言正好相反,即所有东西都必须在一个类中,即使不需要它,从而增加了独立软件块之间的耦合。«
new
as a method»对于一个类型,是的,但对于所有返回值的对象不一定都是如此。它看起来只是不需要,因为只有一个实现。现在应该调用哪个
Builder::new()
呢?这正好回答了为什么不允许这样做。谢谢你能把它作为一个答案发布吗?这样我就可以为其他人清楚地标记它了。它看起来只是不需要的,因为只有一个实现。现在应该调用哪个
Builder::new()
呢?这正好回答了为什么不允许这样做。谢谢你能把它作为一个答案贴出来,这样我就可以为其他人清楚地标记它了吗?