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
推薦閱讀: