为什么编译器需要一个 trait 的实现来调用默认的自由函数? [英] Why does the compiler need an implementation of a trait to call a default free function?

查看:46
本文介绍了为什么编译器需要一个 trait 的实现来调用默认的自由函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当调用一个不带 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 的实现来调用默认的自由函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆