简体   繁体   English

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

[英]Why does the compiler need an implementation of a trait to call a default free function?

When calling a default implementation on a trait which does not take self , why does it neeed an implementing type to be annotated?当对不带self的特征调用默认实现时,为什么需要注释实现类型?

A minimal, reproducible example is below ( playground ):下面是一个最小的、可重复的示例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();
}

Which gives:这使:

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.

The compiler explanation for E0283 does not mention a default implementation, which I agree it makes sense. E0283的编译器解释没有提到默认实现,我同意这是有道理的。 But for default implementations, why is a type required?但是对于默认实现,为什么需要类型?

This is not only a default implementation but the very specific case in which this default implementation does not even mention Self / self in its parameters, result and body.这不仅是默认实现,而且是非常特殊的情况,其中该默认实现在其参数、结果和正文中甚至没有提及Self / self

I find much more easy to understand a rule saying that a type is required every time we use a trait, in any case, rather that « except if the default implementation does not even mention Self / self in its parameters, result and body » .我发现更容易理解的规则是,在任何情况下,每次我们使用 trait 时都需要一个类型,而不是« 除非默认实现在其参数、结果和正文中甚至没有提到Self / self »

For this very specific use case, where you do not want to explicitly name a type when calling the function you need, I suggest using a free function.对于这个非常具体的用例,您不想在调用所需函数时显式命名类型,我建议使用免费函数。

mod builder {
    // ...
    pub fn make_default() -> Simple {
        Simple
    }
    // ...
}

pub fn main() {
    let _ = builder::make_default();
}

Provided methods in Rust are not like static methods in Java. Rust 中提供的方法与 Java 中的static方法不同。 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:考虑添加另一种实现Builder但覆盖new函数的类型:

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();
}

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.如果您想要始终具有相同行为的 Java static函数的效果,则应使用自由函数,正如prog-fh 的回答所建议的那样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 所有特征对象的默认特征方法实现 - Default trait method implementation for all trait objects 为什么这个一揽子特征实现的类型参数不被认为是受约束的? - Why is the type parameter of this blanket trait implementation not considered to be constrained? 为什么 TypeScript 编译器在 function 返回 undefined 而函数的返回类型为数字时不报错? - Why TypeScript compiler does not give error when function returns undefined while function's return type is number? 编译器无法解析默认类型的函数参数 - Compiler Not Resolving Default Typed Function Parameter 为什么Haskell指向函数的自由版本导致模糊类型错误? - Why does Haskell point free version of function result in ambiguous type error? 以特定结构作为参数的特性实现 - Trait implementation with specific struct as parameter 无法调用接受并返回特征中自引用参数化类型的对象的函数 - Cannot call a function that accepts and returns an object of a self-referential parametrised type in a trait 为什么Java编译器不喜欢原始int作为HashMap中值的类型? - Why does the Java compiler not like primitive int as type for values in HashMap? 为什么Glasgow Haskell编译器会在此报告多个类型错误? - Why does the Glasgow Haskell Compiler report multiple type errors here? 为什么这个“prop”的 TS 实现有效,而我的却没有? - Why does this TS implementation of "prop" work but mine does not?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM