参照と借用
参照
所有権を移動せずに値を参照することができます。
借用には不変参照(&T
)と可変参照(&mut T
)があります。
不変参照(&T
)
値を変更できない参照です。複数の不変参照を同時に持つことができます。
#![allow(unused)] fn main() { let s = String::from("hello"); let r1 = &s; // 不変参照 let r2 = &s; // 不変参照 println!("{} and {}", r1, r2); // 出力: hello and hello }
可変参照(&mut T
)
値を変更できる参照です。 ただし、可変参照は一度に一つしか持つことができません。
#![allow(unused)] fn main() { let mut s = String::from("hello"); let r1 = &mut s; // 可変参照 r1.push_str(", world"); println!("{}", r1); // 出力: hello, world println!("{}", s); // 出力: hello, world }
借用
関数の引数に参照を取ることを借用と呼びます。
fn main() { let s1 = String::from("hello"); let len = calculate_length(&s1); // '{}'の長さは、{}です println!("The length of '{}' is {}.", s1, len); } fn calculate_length(s: &String) -> usize { s.len() }
借用のルール
-
不変参照と可変参照を同時に持つことはできない
同じスコープ内で不変参照と可変参照を同時に持つことはできません。これにより、データ競合を防ぎます。
#![allow(unused)] fn main() { let mut s = String::from("hello"); let r1 = &s; // 不変参照 let r2 = &mut s; // エラー: 不変参照が存在する間は可変参照を持てない }
-
可変参照は一度に一つだけ
可変参照は一度に一つしか持つことができません。これにより、データの一貫性を保ちます。
#![allow(unused)] fn main() { let mut s = String::from("hello"); let r1 = &mut s; // 可変参照 let r2 = &mut s; // エラー: 可変参照は一度に一つだけ }
-
可変参照は一度に一つだけ
借用はそのスコープ内でのみ有効です。スコープを抜けると借用は無効になります。
let r; { let s = String::from("hello"); r = &s; // エラー: sのスコープを抜けるとrは無効になる println!("{}", r) } println!("{}", r) // エラー: スコープを抜けたためrは無効
借用の利点
- メモリ安全性: 借用により、所有権を移動せずにデータを安全に操作できます。
- 効率性: 借用を使用することで、不要なデータのコピーを避け、効率的にメモリを使用できます。