Open4

Rustのコレクション

Kentaro AzumaKentaro Azuma

Rustのコレクション

  • コレクションは複数の値を含むことができる
  • 配列やタプルなどの組み込み型とは異なり、コレクションが指すデータはヒープに確保される
  • データ量はコンパイル時にわかっている必要がない
  • プログラムの実行に合わせてデータ量の増減が可能
Kentaro AzumaKentaro Azuma

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ループによるイテレーションで全要素を走査することができる。

Kentaro AzumaKentaro Azuma

文字列

Rustの文字列は非常に複雑であるため、取り扱いには注意が必要である。

str

Rustには言語の核として1種類の文字列型str(文字列スライス)のみが存在する。
通常は借用された形態である&strで見かける。
strは別の場所に格納されたUTF-8文字列データへの参照である。
OsStrCStrなどの関連する型がある。

String

String型は標準ライブラリで提供されるVec<u8>である。
String型は伸長可能、可変、所有権のあるUTF-8文字列型
OsStringCStringなどの関連する型を持つ。

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エンコードされているため、
マルチバイト文字の途中にアクセスする可能性があるからだ。
そうなると、戻り値の型が曖昧になるため、エラーになる。

単独の添字アクセスは禁止する一方で、範囲指定をしてスライスを取得することはできる。
ただし、バイトの境界でない場合はクラッシュする。

forcharsメソッドを組み合わせると、各char毎に処理できる。
forbytesメソッドを組み合わせると、各バイト毎に処理できる。