Rustの参照とスライス
不変参照と可変参照によるデータの借用、aliasing XOR mutabilityルール、スライスの使い方を学びます。
Rust基礎シリーズの第6回です。所有権によってメモリ安全性が保証されますが、すべての場所で値を移動させるとコードが複雑になります。「借用(Borrowing)」を使うと、所有権を奪うことなくデータにアクセスできます。
参照による借用#
参照を使うと、所有権を取得せずに値を参照できます。参照は & 演算子を使用して作成します。
fn calculate_length(s: &String) -> usize {
s.len()
}
fn main() {
let s1 = String::from("hello");
let len = calculate_length(&s1);
println!("'{s1}' の長さは {len} です。");
}rustcalculate_length は参照 &String を受け取るため、s1 は移動せず借用されます。関数呼び出し後も s1 は有効なままです。
可変参照#
デフォルトでは、参照は不変です。借用したデータを変更するには、可変参照 &mut を使用します。
fn change(s: &mut String) {
s.push_str(", world");
}
fn main() {
let mut s = String::from("hello");
change(&mut s);
println!("{s}");
}rust可変参照を作成するには、元の変数も mut で宣言されている必要があります。
借用の根本ルール#
Rustはコンパイル時にデータ競合を防ぐため、以下の厳格なルールを適用します。
ある時点で存在できるのは、任意の数の不変参照 (
&T) または 単一の可変参照 (&mut T) のどちらか一方のみです。両方を同時に持つことはできません。
let mut s = String::from("hello");
let r1 = &s; // OK
let r2 = &s; // OK
// let r3 = &mut s; // エラー: 不変参照が存在するため可変参照は作成できません
println!("{r1} と {r2}");rustこの「エイリアスまたは可変性のどちらか一方のみ」というルールにより、プログラムの他の部分が読み取り中にデータが予期せず変更されるのを防ぎます。
スライス#
スライスは、コレクション全体ではなく、連続した要素のシーケンスへの参照です。
文字列スライス#
文字列スライス (&str) は String の一部を参照します。
let s = String::from("hello world");
let hello: &str = &s[0..5];
let world: &str = &s[6..11];rust文字列リテラル ("hello") は、コンパイルされたバイナリデータへの文字列スライスです。
配列のスライス#
スライスは配列やベクターに対しても使用できます。
let a = [1, 2, 3, 4, 5];
let slice: &[i32] = &a[1..3];
assert_eq!(slice, &[2, 3]);rustまとめ#
参照(& および &mut)による借用により、データを安全に共有できます。スライス(&str および &[T])は、シーケンスへの柔軟な参照ビューを提供します。シリーズの次回テーマは「構造体(Struct)」です。