スライス

スライス型(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]
}