Rust: what "&" means when iterating a vector
常見到當走訪一個vector時,會看到&被放在不同位置,排列組合一下總共有以下四種可能:
let mut v = vec![10; 2];
for i in v {
println!("{}", i);
}
for i in &v {
println!("{}", i);
}
for &i in v {
println!("{}", i);
}
for &i in &v {
println!("{}", i);
}
這篇文章想試著解釋一下各個的不同。
看文件
首先看iterator loop文件,可以觀察到語法 for "element" in "arr"
,兩個地方要填的東西不太一樣。
以下節錄自文件:
Syntax IteratorLoopExpression : for Pattern in Expressionexcept struct expression BlockExpression
element
要填的是pattern,arr
要填的則是expression。因此&的用法在這兩處地方也會有所差異。
&arr
: 這裡的&用在expression,意思是宣告一個arr的reference,因此for迴圈拿到的東西都是陣列裡面個元素的reference&element
: 這裡的&用在pattern,是pattern matching語法中的一種。詳情可以看文件。
知道差異後,就可以來看下四種case的不同之處了。
1. for i in v
因為v是直接傳入,所以這裡會把v裡面的元素move,轉移所有權。
在for迴圈結束之後就不能再使用v了。
2. for i in &v
注意這裡的i的型別是&i32,不是i32。一班正常使用,甚至做加減運算都可以正常運作,一班人很容易誤會。
3. for &i in v
因為v傳入的型別不是參考,而是i32,所以會編譯錯誤。
4. for &i in &v
這裡的&i試著match &i32,因此i的型別是i32。
這裡會有另個疑問是: 如果match的type不是單存的i32,而是一個object會發生甚麼事情?