🎃
【Rust】配列の繰り返し処理の借用
はじめに
Rustで、以下のようなループ処理をするとどのような結果となるでしょうか?
結果は、println!("{:?}", numbers)で、エラーが発生します。
理由は、numbersのループ処理で所有権がnumberに移動するからです。
fn main() {
let mut numbers = Vec::new();
numbers.push(1);
numbers.push(2);
numbers.push(3);
for number in numbers {
println!("{}", number);
}
println!("{:?}", numbers);
}
Rustは所有権が別な変数に所有権が移った後は再度呼べない決まりがあります。
さらに、上の処理のループについて話すと、forはデフォルトで以下のように、into_iterをつけて処理をしています。
この処理は配列に対してイテレータを作成し所有権を移す処理となります。
つまり、numbersの所有権をnumberに移動させているので、この後の処理でnumbersを呼び出そうとするとエラーとなっているのです。
for number in numbers.into_iter() {
println!("{}", number);
}
所有権の移動によるエラーが発生しない方法としては、以下のように"借用"を使う方法があります。
&を使う
numbersの参照(&Vec<i32>)を取得して渡す方法。
ループの中で、numberは&i32型(要素の参照)となります。。
借用対象:&Vec<i32>
fn main() {
let mut numbers = Vec::new();
numbers.push(1);
numbers.push(2);
numbers.push(3);
for number in &numbers {
println!("{}", number);
}
println!("{:?}", numbers);
}
iter()を使う
numbersからイテレータの参照を取得(明示的にイテレータを作る)して渡す方法。
ループの中で、numberは&i32型(要素の参照)となります。
借用対象:Iter<i32>
fn main() {
let mut numbers = Vec::new();
numbers.push(1);
numbers.push(2);
numbers.push(3);
for number in numbers.iter() {
println!("{}", number);
}
println!("{:?}", numbers);
}
おわりに
配列の繰り返しでも所有権が移動することで変数を呼び出すことができないエラーに直面することがあります。その場合は、ループ処理で借用を使えば所有権が移動せずに再度変数を呼び出すことができるようになります。
Discussion