Rustのコレクション
Rustのコレクション
- コレクションは複数の値を含むことができる
- 配列やタプルなどの組み込み型とは異なり、コレクションが指すデータはヒープに確保される
- データ量はコンパイル時にわかっている必要がない
- プログラムの実行に合わせてデータ量の増減が可能
Vec<T>
ベクタは同じ型の値を複数保持でき、それらの値をメモリ上に隣り合わせに並べる。
空のベクタはVec::new
関数によって生成できる。
vec!
というマクロもある。
push
メソッドを使用することで要素を追加できる。
ベクタがスコープを抜けるとき、保持していた値もドロップする。
let mut v = Vec::new();
v.push(5);
v.push(6);
ベクタに保持された値を参照する方法は2種類ある。
- 添字を使用する
-
get
メソッドを使用する
添字を使用する場合、範囲外の場合にはパニックを起こす。
一方でget
メソッドはOption<&T>
を返すため、範囲外の場合はNone
を返す
ベクタは要素を追加する際にメモリが足りなければ、新しい領域に確保し直すため、
参照先がいつの間にかいなくなる可能性がある。
したがって、不変な参照がある場合にはpush
メソッドで要素を追加できない。
ベクタはforループによるイテレーションで全要素を走査することができる。
文字列
Rustの文字列は非常に複雑であるため、取り扱いには注意が必要である。
str
Rustには言語の核として1種類の文字列型str
(文字列スライス)のみが存在する。
通常は借用された形態である&str
で見かける。
str
は別の場所に格納されたUTF-8文字列データへの参照である。
OsStr
、CStr
などの関連する型がある。
String
String
型は標準ライブラリで提供されるVec<u8>
である。
String
型は伸長可能、可変、所有権のあるUTF-8文字列型
OsString
、CString
などの関連する型を持つ。
let mut s = String::new();
let data = "initial contents";
let s = data.to_string()
let s = "initial contents".to_string
let s = String::from("initial contents");
str.to_string()
は内部でString::from
を呼び出すため、
どちらを使用してもよい。
String
にデータを追加するには以下の方法がある。
-
push_str
メソッドに&str
を渡す -
push
メソッドにchar
を渡す -
+
演算子を使用する -
format!
マクロを使用する
let mut s = String::from("foo");
s.push_str("ba");
s.push('r');
let s1 = String::from("Hello");
let s2 = String::from("World");
let s3 = s1 + &s2;
let s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("toe");
let s4 = format!("{}-{}-{}", s1, s2, s3);
文字列の読み出し
Rustの文字列は添字によるアクセスをサポートしていない。
文字列はUTF-8エンコードされているため、
マルチバイト文字の途中にアクセスする可能性があるからだ。
そうなると、戻り値の型が曖昧になるため、エラーになる。
単独の添字アクセスは禁止する一方で、範囲指定をしてスライスを取得することはできる。
ただし、バイトの境界でない場合はクラッシュする。
for
とchars
メソッドを組み合わせると、各char毎に処理できる。
for
とbytes
メソッドを組み合わせると、各バイト毎に処理できる。