複合型
複合型は、複数の値をまとめて一つの型として扱うことができるデータ型です。Rustには主に以下の複合型があります。
タプル型
タプル型は、異なる型の値をまとめて一つのグループとして扱います。タプルはカンマ区切りの値を丸括弧で囲んで作成します。 また、タプルから値を取り出すには、パターンマッチングを使用して分解することができます。
fn main() { let tuple: (i32, f64, char) = (42, 3.14, 'a'); let (x, y, z) = tuple; // パターンマッチングで値を取り出す println!("Tuple: ({}, {}, {})", x, y, z); }
タプルから特定の要素を取り出すには、インデックスも使用できます。インデックスは0から始まります。
fn main() { let tuple: (i32, f64, char) = (42, 3.14, 'a'); println!("First element: {}", tuple.0); println!("Second element: {}", tuple.1); println!("Third element: {}", tuple.2); }
配列型
配列型は、同じ型の値を固定長の配列として扱います。配列は角括弧で囲んで作成します。
ベクタを生成するには、vec!
マクロやVec::new
メソッドを使用します。
fn main() { let array: [i32; 3] = [1, 2, 3]; println!("Array: {:?}", array); println!("First element: {}", array[0]); println!("Second element: {}", array[1]); println!("Third element: {}", array[2]); }
ベクタ型
ベクタ型(Vec<T>
)は、動的にサイズを変更できる可変長の配列です。
- 可変長: 実行時にサイズを変更できます。
- ヒープメモリ: 要素はヒープに格納されます。
- 型安全: ベクタ内のすべての要素は同じ型でなければなりません。
#![allow(unused)] fn main() { // vec!マクロを使用 let v = vec![1, 2, 3]; // Vec::newを使用 let mut v: Vec<i32> = Vec::new(); v.push(1); v.push(2); v.push(3); }
ベクタの操作
ベクタには多くの便利なメソッドがあります。以下にいくつかの例を示します:
- 要素の追加:
push
- 要素の削除:
pop
- 要素の挿入:
insert
- 要素の削除:
remove
- 長さの取得:
len
- 空チェック:
is_empty
- 全要素の削除:
clear
fn main() { let mut v = vec![1, 2, 3]; v.push(4); // 末尾に要素を追加 v.pop(); // 末尾の要素を削除 v.insert(1, 10); // インデックス1に要素を挿入 v.remove(1); // インデックス1の要素を削除 println!("ベクタの長さ: {}", v.len()); // 長さを取得 println!("ベクタは空か?: {}", v.is_empty()); // 空チェック v.clear(); // 全要素を削除 }
タプル型は要素数、配列型は長さと型が固定されているため、柔軟なデータ管理が難しいです。 一方、ベクタ型は動的にサイズを変更できるため、メモリの再割り当てが発生することがあり、これがパフォーマンスに影響を与えることがあります。また、ベクタの初期化には配列よりもコストがかかる場合があります。
特徴
タプル型 | 配列型 | ベクタ型 | |
---|---|---|---|
要素 | 異なる型の要素を持つことができる | 同じ型の要素のみ | 同じ型の要素のみ |
要素数 | 固定 | 固定(長さ) | 可変 |
要素へのアクセス | インデックスまたはパターンマッチング | インデックス | インデックス |
用途 | 関数から複数の値を返す、一時的なデータのグループ化 | 固定長のデータ、ループ処理やインデックスを使ったアクセス | 動的にサイズを変更できるデータ、可変長のデータ、頻繁な追加や削除が必要な場合 |