📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

概要

コレクション型は、複数のデータを効率的に管理するためのデータ構造である。

Rustのコレクション型は、ヒープ上にデータを格納し、コンパイル時にサイズが決まっていなくても使用できる。
用途に応じて適切なコレクション型を選択することで、効率的なプログラムを作成することができる。


コレクション型の選択

用途に応じて適切なコレクション型を選択することが重要である。

  • 順序付きリスト
    Vec<T>
  • キー・値の検索
    HashMap<K, V>
  • 重複排除
    HashSet<T>
  • 両端操作
    VecDeque<T>
  • ソート済み
    BTreeMap<K, V> / BTreeSet<T>
  • 優先度管理
    BinaryHeap<T>



Vec<T> : 可変長配列

Vec<T>は、動的にサイズが変わる配列型である。
連続したメモリ領域に要素を格納し、インデックスによる高速なアクセスが可能である。
順序付きリストが必要な場合に使用する。

 fn main() {
    let mut v = vec![1, 2, 3];
    v.push(4);
    v.push(5);
 
    println!("{:?}", v);
 
    // インデックスでアクセス
    println!("{}", v[0]);
 
    // 要素の削除
    v.pop();
    println!("{:?}", v);
 }
 
 // 出力
 [1, 2, 3, 4, 5]
 1
 [1, 2, 3, 4]



HashMap<K, V> : ハッシュマップ

HashMap<K, V>は、キーと値のペアを格納するコレクション型である。

キーを指定することで、対応する値を高速に検索できる。
キーと値の検索が必要な場合に使用する。

 use std::collections::HashMap;
 
 fn main() {
    let mut scores = HashMap::new();
 
    scores.insert("Blue", 10);
    scores.insert("Red", 50);
 
    // 値の取得
    let score = scores.get("Blue");
    println!("{:?}", score);
 
    // キーが存在するか確認
    if scores.contains_key("Blue") {
       println!("Blue team exists");
    }
 
    // 全要素の走査
    for (key, value) in &scores {
       println!("{}: {}", key, value);
    }
 }
 
 // 出力
 Some(10)
 Blue team exists
 Blue: 10
 Red: 50



HashSet<T> : ハッシュセット

HashSet<T>は、重複のない値の集合を表すコレクション型である。

値の存在確認が高速に行うことができるる。
重複を排除する場合に使用する。

 use std::collections::HashSet;
 
 fn main() {
    let mut set = HashSet::new();
 
    set.insert(1);
    set.insert(2);
    set.insert(2); // 重複は無視される
 
    println!("{:?}", set);
 
    // 値の存在確認
    if set.contains(&1) {
       println!("1 is in the set");
    }
 
    // 要素数
    println!("Size: {}", set.len());
 }
 
 // 出力
 {1, 2}
 1 is in the set
 Size: 2



VecDeque<T> : 両端キュー

VecDeque<T>は、先頭と末尾の両方から効率的に要素を追加・削除できるコレクション型である。

両端操作が頻繁に必要な場合に使用する。

 use std::collections::VecDeque;
 
 fn main() {
    let mut deque = VecDeque::new();
 
    // 末尾に追加
    deque.push_back(1);
    deque.push_back(2);
 
    // 先頭に追加
    deque.push_front(0);
 
    println!("{:?}", deque);
 
    // 先頭から削除
    deque.pop_front();
 
    // 末尾から削除
    deque.pop_back();
 
    println!("{:?}", deque);
 }
 
 // 出力
 [0, 1, 2]
 [1]



BTreeMap<K, V> / BTreeSet<T> : ソート済みマップ・セット

BTreeMap<K, V>とBTreeSet<T>は、キーがソートされた状態で保持されるコレクション型である。

順序付きの走査が必要な場合や、範囲検索を行いたい場合に使用する。

 use std::collections::BTreeMap;
 
 fn main() {
    let mut map = BTreeMap::new();
 
    map.insert(3, "three");
    map.insert(1, "one");
    map.insert(2, "two");
 
    // キーがソートされた順で出力される
    for (key, value) in &map {
       println!("{}: {}", key, value);
    }
 }
 
 // 出力
 1: one
 2: two
 3: three


 use std::collections::BTreeSet;
 
 fn main() {
    let mut set = BTreeSet::new();
 
    set.insert(5);
    set.insert(1);
    set.insert(3);
 
    // ソートされた順で出力される
    for value in &set {
       println!("{}", value);
    }
 }
 
 // 出力
 1
 3
 5



BinaryHeap<T> : 優先度キュー

BinaryHeap<T>は、最大値を効率的に取り出せる優先度キューである。

優先度管理が必要な場合に使用する。

 use std::collections::BinaryHeap;
 
 fn main() {
    let mut heap = BinaryHeap::new();
 
    heap.push(3);
    heap.push(1);
    heap.push(5);
    heap.push(2);
 
    // 最大値から順に取り出される
    while let Some(value) = heap.pop() {
       println!("{}", value);
    }
 }
 
 // 出力
 5
 3
 2
 1



LinkedList<T> : 連結リスト

LinkedList<T>は、双方向連結リストである。

実際の使用では、Vec<T>の方が効率的なことが多いため、あまり使用されない。

 use std::collections::LinkedList;
 
 fn main() {
    let mut list = LinkedList::new();
 
    list.push_back(1);
    list.push_back(2);
    list.push_front(0);
 
    println!("{:?}", list);
 }
 
 // 出力
 [0, 1, 2]



文字列型

String : 所有権を持つ文字列

Stringは、所有権を持つ可変長の文字列型である。

文字列の内容を変更する必要がある場合に使用する。

 fn main() {
    let mut s = String::from("hello");
    s.push_str(" world");
 
    println!("{}", s);
 }
 
 // 出力
 hello world


&str : 文字列スライス

&strは、文字列への参照を表す型である。

文字列を読み取るだけで変更しない場合に使用する。

 fn main() {
    let s: &str = "hello";
    println!("{}", s);
 }
 
 // 出力
 hello



Option型とResult型

Option<T> : 値があるかないか

Option<T>は、値が存在するかしないかを表す型である。

Some(value)で値がある状態、Noneで値がない状態を表す。

 fn main() {
    let some_number = Some(5);
    let no_number: Option<i32> = None;
 
    match some_number {
       Some(n) => println!("Number: {}", n),
       None => println!("No number"),
    }
 
    match no_number {
       Some(n) => println!("Number: {}", n),
       None => println!("No number"),
    }
 }
 
 // 出力
 Number: 5
 No number


Result<T, E> : 成功または失敗

Result<T, E>は、処理の成功または失敗を表す型である。

Ok(value)で成功、Err(error)で失敗を表す。
これは、エラー処理が必要な場合に使用する。

 fn divide(a: i32, b: i32) -> Result<i32, String> {
    if b == 0 {
       Err(String::from("division by zero"))
    }
    else {
       Ok(a / b)
    }
 }
 
 fn main() {
    match divide(10, 2) {
       Ok(result) => println!("Result: {}", result),
       Err(e) => println!("Error: {}", e),
    }
 
    match divide(10, 0) {
       Ok(result) => println!("Result: {}", result),
       Err(e) => println!("Error: {}", e),
    }
 }
 
 // 出力
 Result: 5
 Error: division by zero



共通のメソッド

lenメソッドで要素数を取得する

多くのコレクション型は、lenメソッドで要素数を取得することができる。

 fn main() {
    let v = vec![1, 2, 3, 4, 5];
    println!("Length: {}", v.len());
 }
 
 // 出力
 Length: 5


is_emptyメソッドで空かどうか確認する

コレクションが空かどうかを確認するには、is_empty メソッドを使用する。

 fn main() {
    let v: Vec<i32> = Vec::new();
    println!("Is empty: {}", v.is_empty());
 
    let v2 = vec![1, 2, 3];
    println!("Is empty: {}", v2.is_empty());
 }
 
 // 出力
 Is empty: true
 Is empty: false


clear関数で全要素を削除する

コレクションの全要素を削除するには、clear メソッドを使用する。

 fn main() {
    let mut v = vec![1, 2, 3, 4, 5];
    println!("Before: {:?}", v);
 
    v.clear();
    println!("After: {:?}", v);
 }
 
 // 出力
 Before: [1, 2, 3, 4, 5]
 After: []