我正在阅读Rust by Examples。
下面的代码有效。
println!("Bar + Foo = {:?}", Bar + Foo);
但是,尽管struct和trait实施都在范围内,但以下内容不起作用。
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;
|
为什么不呢?
答案 0 :(得分:3)
如编译器所说:
特征中的项目只能在特征处于范围内时使用
只需执行编译器的建议即可
use std::ops::Add;
fn main() {
println!("Foo + Bar = {:?}", Foo + Bar);
println!("Foo + Bar = {:?}", Foo.add(Bar));
}
要明确:
“ 尽管struct和trait实施都在范围内,但下面的方法不起作用”
这是不正确的,特征Add
不在范围内,您只有ops
模块,这与use std::ops::Add;
完全不同。您还可以看到,在实现中,您写的是ops::Add<Bar>
而不是Add<Bar>
,所以Add
不在代码范围之内,只是ops
。
如果只能在特征范围内使用特征中的项目,那么“ Foo + Bar”如何工作? “ +”和“添加”有什么区别?
+
只是语法糖,编译器为您完成了一件神奇的事情。它的工作原理并不重要,+
不需要任何调用add()
(因为它是内置函数,编译器“知道”该怎么做),但是如果您自己调用它,则编译器可以没有理由不应用关于特征的一般规则,也没有关于在范围内导入该特征的规则(默认情况下会导入某些特征,但不会导入Add
)。 +
是特殊特征,但不是Add
特征。 ?
运算符也是如此,锈蚀更多。我们使用trait来实现一些基本的运算符,这确实很干净而且非常灵活。