Rust Quiz 解读:Quiz 15
来自于RustFest 2018 大会上Alex Crichton 和 David Tolnay两位大佬的轻演讲主题:Rust Quiz
- rust-quiz源码- 在线练习和解答- 视频
不得不说,两位大佬出的题非常具有迷惑性,一不留神就落入了陷阱。
Quiz 15:
下面这段代码输出什么?
trait Trait {
fn f(&self);
}
impl Trait for u32 {
fn f(&self) {
print!("1");
}
}
impl<a> Trait for &a i32 {
fn f(&self) {
print!("2");
}
}
fn main() {
let x = &0;
x.f();
}
输出结果: 1
解读
考察要点:
- trait实现
T
和&a T
的区别- 类型推断
- 自动加引用
其实Quiz 15和Quiz 5的考察点是相似的。主要是考察T
和&T
有啥区别呢?虽然这里是u32
和&』a i32
。
- T, 是一个泛型参数,代表任何一个具体的类型。
- &T,实际上等价于
&a T
,代表某个引用类型。注意这里的a
也是一个泛型参数,并不是指具体的类型。
main函数中直接使用了let x = &0;
,&0
实际上是一个包含了具体生命周期参数实例的具体类型&a 0
。所以,&0
实际上会被推断为一个具体的T
类型的实例u32
。
这和impl Trait for ...
的定义顺序无关。不妨把impl<a> Trait for &a i32 { ... }
和impl Trait for u32 { ... }
的顺序交换,输出结果照样不变。
此时在u32
的f
方法实现中self
是&u32
。
所以,x.f()
会输出1
。
如果把impl Trait for u32 {}
实现注释掉。则 x.f()
会输出2
。
trait Trait {
fn f(&self);
}
impl<a> Trait for &a i32 {
fn f(&self) {
print!("2");
}
}
fn main() {
let x = &0;
x.f();
}
在这个代码中,f
方法中的self
会被自动加引用为&&0
。
点此查看 Rust Quiz 15
推荐阅读: