到達点は、可変長データと文字列を、所有権を意識して扱うことです。前提は第05〜07回です。
要素を増やすと場所が変わることがある
Vecは連続領域に要素を持つ可変長配列です。pushで容量を超えると再確保が起きる場合があります。要素への参照を使っている最中にVecを変更できないケースがあるのは、参照先の移動を防ぐためです。
use std::collections::HashMap;
fn main() {
let mut minutes = vec![25, 15];
minutes.push(30);
println!("{:?}", minutes.get(9));
let mut counts = HashMap::new();
for word in ["rust", "java", "rust"] {
*counts.entry(word).or_insert(0) += 1;
}
let mut pairs: Vec<_> = counts.into_iter().collect();
pairs.sort_by_key(|(word, _)| *word);
println!("{:?}", pairs);
let text = String::from("Aあ😀");
println!("{} {}", text.len(), text.chars().count());
println!("{:?}", text.get(1..4));
println!("{:?}", text.get(1..2));
}
src/main.rsの出力はNone、javaが1とrustが2、8と3、「あ」のSome、Noneです。StringのlenはUTF-8のバイト数です。charsはUnicodeスカラー値を取り出し、人が認識する一文字と常に一致するわけではありません。
文字列を整数の添字で切らない
Stringに text[0] のようなアクセスはできません。UTF-8では一つの文字が複数バイトになるため、意図が曖昧です。バイト範囲のスライスでも文字境界を守る必要があります。getなら不正な境界をNoneで返せます。
HashMapはキーから値を検索し、entryは未登録なら初期値を入れる処理に向きます。反復順は安定した表示順として頼れないので、例ではソートしました。順序付きのキー操作が必要ならBTreeMapも候補です。
練習と解答
練習:先頭のUnicodeスカラー値を安全に取得してください。空文字列も扱います。
解答:text.chars().next() がOption<char>を返します。不在ならNoneです。ただし、家族の絵文字や結合文字を「見た目の一文字」で切るには、書記素クラスタの扱いが必要です。文字数制限の仕様を、バイト数やcharsの数と混同しないようにします。
公式資料
コレクションとString APIが参照先です。
Rust全20回の目次 | 前の回 | 次の回