跳至主要内容

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會發生甚麼事情?