impl Trait 的原语和引用
impl Trait for primitives and references of
也许这是一个简单的问题,但我不明白为什么只是为原始的、拥有的类型实现 Trait,我免费获得了相同的引用类型实现...
trait Cool: Sized + std::fmt::Debug {
fn cool(self) {
println!("cool -> {:?}", self);
}
}
impl Cool for i32 {}
// it still works if this line is uncommented...
// impl Cool for &i32 {}
fn main(){
let val = 123;
val.cool();
(&val).cool();
}
这不仅仅是因为原语,它适用于实现 Copy
的所有类型。否则将不起作用:
trait Cool: Sized + std::fmt::Debug {
fn cool(self) {
println!("cool -> {:?}", self);
}
}
#[derive(Debug)]
struct NonCopy;
impl Cool for i32 {}
impl Cool for NonCopy {}
fn main(){
let val = 123;
val.cool();
(&val).cool();
let nc = NonCopy{};
nc.cool();
(&nc).cool();
}
失败并显示明确的错误代码:
error[E0507]: cannot move out of a shared reference
--> src/main.rs:20:5
|
20 | (&nc).cool();
| ^^^^^^------
| | |
| | value moved due to this method call
| move occurs because value has type `NonCopy`, which does not implement the `Copy` trait
|
发生的事情是,使用 Copy 类型时,rust 会在需要时透明地为您创建一个副本。
请注意,即使我们注释掉前一行 // nc.cool();
,它也会失败,这显然移动了值...
那是auto-dereferencing;只要您使用 .
运算符,它就适用。它旨在消除 C 和相关语言中存在的 .
和 ->
之间的区别。
它是在 RFC 241 中引入的。
也许这是一个简单的问题,但我不明白为什么只是为原始的、拥有的类型实现 Trait,我免费获得了相同的引用类型实现...
trait Cool: Sized + std::fmt::Debug {
fn cool(self) {
println!("cool -> {:?}", self);
}
}
impl Cool for i32 {}
// it still works if this line is uncommented...
// impl Cool for &i32 {}
fn main(){
let val = 123;
val.cool();
(&val).cool();
}
这不仅仅是因为原语,它适用于实现 Copy
的所有类型。否则将不起作用:
trait Cool: Sized + std::fmt::Debug {
fn cool(self) {
println!("cool -> {:?}", self);
}
}
#[derive(Debug)]
struct NonCopy;
impl Cool for i32 {}
impl Cool for NonCopy {}
fn main(){
let val = 123;
val.cool();
(&val).cool();
let nc = NonCopy{};
nc.cool();
(&nc).cool();
}
失败并显示明确的错误代码:
error[E0507]: cannot move out of a shared reference
--> src/main.rs:20:5
|
20 | (&nc).cool();
| ^^^^^^------
| | |
| | value moved due to this method call
| move occurs because value has type `NonCopy`, which does not implement the `Copy` trait
|
发生的事情是,使用 Copy 类型时,rust 会在需要时透明地为您创建一个副本。
请注意,即使我们注释掉前一行 // nc.cool();
,它也会失败,这显然移动了值...
那是auto-dereferencing;只要您使用 .
运算符,它就适用。它旨在消除 C 和相关语言中存在的 .
和 ->
之间的区别。
它是在 RFC 241 中引入的。