使い方がややこしい。C#のほうが直感的。
成果物
参考
コード
use
use std::collections::HashMap;
最初に必要。
生成
let mut map = HashMap::new();
空のハッシュマップを生成する。mut
にしないとinsert
などができず使い物にならない。
挿入
let mut map = HashMap::new(); map.insert("A".to_string(), 100); map.insert("B".to_string(), 100);
insert(キー, 値)
とする。
ドキュメントではString型だが、str型でもできた。
なお、同一キーにおける2回目以降のinsert
は、値を更新することになる。
所有権
所有権はムーブする。
let key = "key1".to_string(); let value = 100; let mut map = HashMap::new(); map.insert(key, value); // 所有権がムーブされる(key,value) error[E0382]: use of moved value: `key` println!("{:?}", map); println!("{} {}", key, value); // key, valueの所有権を失っているのでエラー
取得
let mut map = HashMap::new(); map.insert("A".to_string(), 100); println!("{:?}", scores.get(&"A".to_string())); // Some(1)
get()
はOption<&V>
を返す
なんか複雑。以下のせい。
&
to_string()
がウザい{:?}
型やそれにより生じる違いによってコードを書かねばならない苦痛。scores.get("A"); // 1
みたいに使いたいのだが……。
もう少し簡略化したのが以下。
let mut map = HashMap::new(); map.insert("A".to_string(), 100); println!("{:?}", scores.get("A")); // Some(1)
文字列リテラルならget
の引数に&
が不要。
- なぜ
get
の&
が必要か?- 引数の所有権が呼出元から
get
関数へムーブしないように、そう設計したと思われる
- 引数の所有権が呼出元から
- なぜ文字列リテラルなら
&
が不要か?- 文字列リテラルは
&str
型だから
- 文字列リテラルは
- なぜString型で
insert
したのにstr型でget
できるのか?- わからん
走査
let mut map = HashMap::new(); map.insert("A".to_string(), 1); map.insert("B".to_string(), 2); for (key, value) in &scores { println!("{}: {}", key, value); }
カウント
let text = "A B A C"; let mut words_count = HashMap::new(); for word in text.split_whitespace() { let count = words_count.entry(word).or_insert(0); *count += 1; } println!("{:?}", words_count);
{"C": 1, "A": 2, "B": 1}
- struct HashMap
entry()
: Entryを取得する
- enum HashMap::Entry: キーと値の型
or_insert()
: 値の可変参照を返す。ただし値が空のときは引数値を設定する
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13
- bash 4.4.12(1)-release
$ uname -a Linux raspberrypi 4.19.42-v7+ #1219 SMP Tue May 14 21:20:58 BST 2019 armv7l GNU/Linux
前回まで
- Rustを学んでみたい(プログラミング言語)
- Rustの環境構築
- RustでHelloWorld
- Rustの和訳ドキュメント
- Cargoでプロジェクト作成・ビルド・実行
- クレートとは?
- Rustで関数を使ってみる
- Rustでモジュールを使ってみる
- Rustで乱数を生成する(rand)
- Rustで標準入力する(std::io::stdin().read_line())
- RustでMatch判定する(match)
- Rustでprintとread_lineを1行にする方法
- Rustで数当てゲーム
- クレート名にドット.が使えない
- Rustの変数と可変性(let, mut) error[E0384]: cannot assign twice to immutable variable
x
- Rustのimmutable束縛とconst定数の違い
- RustのREPL、evcxrのインストールに失敗した
- Rustでコンパイルするときの変数未使用warningを消す
- Rustの変数(再代入、再宣言(シャドーイング))
- Rustのシャドーイングについて
- イミュータブルについて(副作用)
- Rustの定数(const)
- Rustのデータ型(数値)
- Rustのデータ型(論理)
- Rustのデータ型(文字)
- Rustのデータ型(タプル)
- Rustのデータ型(配列)
- Rustの関数
- Rustのif式
- Rustのくりかえし文(loop)
- Rustのくりかえし文(while)
- Rustのくりかえし文(for)
- Rustの所有権(ムーブ)
- Rustの所有権(関数)
- Rustの所有権(スライス)
- Rustの構造体(定義とインスタンス化)
- Rustの構造体(プログラム例)
- Rustの構造体(メソッド)
- Rustの列挙型(enum)
- Rustの列挙型(enum)
- Rustの列挙型(enum)
- Rustのmatch(制御フロー演算子)
- RustでNULLを扱う(Option, Some, None)
- NULL参照は10億ドルの失敗だった
- Rustの列挙型に独自表示を実装する(E0277 対策 std::fmt::Display 実装)
- RustのIfLet(matchの糖衣構文)
- Rustのプロジェクト構造
- Rustのcargoでライブラリ&テスト(単体、結合)
- Rustのモジュール(mod)
- Rustのモジュール(pub)
- Rustのmod参照方法(
mod 子モジュール名;
,use 要素名;
,extern crate クレート名;
,super
) - Rustのインポートまとめ(Rust2018)
- RustのコレクションVec型
- RustのコレクションString型