添加和+之间的区别?

Difference between add and +?

我正在阅读Rust by Examples

下面的代码有效。

println!("Bar + Foo = {:?}", Bar + Foo);

但是,尽管结构和特征实现都在范围内,但以下内容不起作用。

println!("Bar + Foo = {:?}", Bar.add(Foo));

完整代码:

use std::ops;

struct Foo;
struct Bar;

#[derive(Debug)]
struct FooBar;

impl ops::Add<Bar> for Foo {
    type Output = FooBar;

    fn add(self, _rhs: Bar) -> FooBar {
        println!("> Foo.add(Bar) was called");

        FooBar
    }
}

fn main() {
    println!("Foo + Bar = {:?}", Foo + Bar);
    println!("Foo + Bar = {:?}", Foo.add(Bar));
}

错误:

error[E0599]: no method named `add` found for type `Foo` in the current scope
  --> src/main.rs:21:38
   |
3  | struct Foo;
   | ----------- method `add` not found for this
...
21 |     println!("Foo + Bar = {:?}", Foo.add(Bar));
   |                                      ^^^
   |
   = help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope, perhaps add a `use` for it:
   |
1  | use std::ops::Add;
   |

为什么不呢?

正如编译器所说:

items from traits can only be used if the trait is in scope

按照编译器的建议去做:

use std::ops::Add;

fn main() {
    println!("Foo + Bar = {:?}", Foo + Bar);
    println!("Foo + Bar = {:?}", Foo.add(Bar));
}

要清楚:

"虽然结构和特征实现都在范围内,但以下内容不起作用"

这是不正确的,特征 Add 不在范围内,您只有 ops 模块,这与 use std::ops::Add; 完全不同。您还可以看到,在您的实现中,您写的是 ops::Add<Bar> 而不是 Add<Bar>,因此 Add 不在您代码的范围内,只是 ops.

If items from traits can only be used if the trait is in scope, then how "Foo + Bar" works? What is difference between "+" and "add"?

+ 只是一个语法糖,是编译器为你做的一件神奇的事情。它如何工作并不重要,+ 不需要任何东西来调用 add()(因为它是内置的,编译器 "know" 做什么)但是如果你自己调用它,编译器没有理由不应用关于 trait 的一般规则以及关于在范围内导入该 trait 的规则(某些 trait 默认导入但不是 Add)。 + 是特殊但不是 Add 特征。这同样适用于 ? 运算符和更多 rust。我们使用 trait 来实现一些基本的运算符,这真的很干净而且非常灵活。