スライス
スライス型(slice)は、Rustで配列やベクタの一部を参照するための型です。 スライスは所有権を持たず、元のデータを参照するだけなので、メモリの効率的な利用が可能です。
#![allow(unused)] fn main() { let s1 = String::from("hello"); let s2 = &s1; // s2は&s1の文字列スライス }
このコードでは、s1はString型であり、ヒープに格納された可変長の文字列データを持っています。 一方、s2はs1の参照であり、文字列スライス型(&str)というスライス型です。 s2を通じてs1のデータを読み取ることができます。
特徴
-
参照型
スライスは常に参照であり、元のデータの一部を指し示します。
&[T]
や&mut [T]
の形で定義されます。 -
不変スライスと可変スライス
- 不変スライス:
&[T]
。元のデータを変更できません。 - 可変スライス:
&mut [T]
。元のデータを変更できます。
- 不変スライス:
-
動的サイズ
スライスは動的にサイズを変更でき、配列やベクタの一部を切り出して使用できます。
#![allow(unused)] fn main() { // 配列から不変スライスを生成 let arr = [1, 2, 3, 4, 5]; let slice = &arr[1..4]; // [2, 3, 4] // ベクタから可変スライスを生成 let mut vec = vec![1, 2, 3, 4, 5]; let slice_mut = &mut vec[1..4]; // [2, 3, 4] slice_mut[0] = 10; // スライスを介して元のベクタを変更 }
スライスの利点
-
効率的なメモリ使用
スライスは元のデータを参照するだけなので、メモリのコピーが発生しません。
-
柔軟性
配列やベクタの一部を簡単に操作でき、コードの再利用性が高まります。
-
安全性
Rustの所有権システムと借用規則により、スライスを使用してもメモリの安全性が保たれます。
使用例
fn main() { let arr = [1, 2, 3, 4, 5]; let slice = &arr[1..4]; // [2, 3, 4] println!("{:?}", slice); // 出力: [2, 3, 4] let mut vec = vec![1, 2, 3, 4, 5]; let slice_mut = &mut vec[1..4]; // [2, 3, 4] slice_mut[0] = 10; // スライスを介して元のベクタを変更 println!("{:?}", vec); // 出力: [1, 10, 3, 4, 5] }