スライス型(Rust)

スライス型の話がおもしろい。

Q. 文字列を受け取って、その文字列中の最初の単語を返す関数を書いてください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
fn first_word(s: &str) -> &str {
let bytes = s.as_bytes(); // バイト列に変換して1文字ずつ調べやすくする

for (i, &item) in bytes.iter().enumerate() {
if item == b' ' { // スペースを見つけたら
return &s[0..i]; // 0番目からi番目までのスライスを返す
}
}

&s[..] // スペースがなければ文字列全体を返す
}

fn main() {
let my_string = String::from("Hello Rust World");

// String全体のスライスを渡す
let word = first_word(&my_string);

println!("最初の単語は: {}", word); // "Hello"
}

?. なぜこの設計が優れているか.

  1. メモリ効率(ゼロコピー)
    もし戻り値を String にした場合、最初の単語をコピーして新しいメモリ領域を確保する必要がある。しかし、&str を返せば、元の String のアドレスと長さを返すだけなので、データ量に関わらず一瞬で終わる。
  2. コンパイル時の安全性
    これがRustの凄いところ、もし以下のようなコードを書こうとすると、Rustはコンパイルエラーを出して防いでくれる。
1
2
3
4
5
6
let mut my_string = String::from("Hello Rust");
let word = first_word(&my_string); // 'word' は 'my_string' の一部を借用中

my_string.clear(); // エラー!借用中に中身を消すことはできない

println!("{}", word); // もし許可されたら、ここで「ダングリングポインタ」になる!

C++とかの言語では、元データが消えたことに気づかずに word(ダングリングポインタ)にアクセスしてクラッシュする可能性がある、けどRustは 「貸している間は元データを変えさせない」 というルールでこれを防げる。

Author

kiku

Posted on

2026-10-05

Updated on

2026-10-05

Licensed under