100日後にRustをちょっと知ってる人になる: [Day 7]API リファレンス
Day 7 のテーマ
昨日の続きで、「数当てゲーム」を作りながら、Rust の言語仕様を見ていきます。
数当てゲームの実装
以下の内容を追加で実装していきます。
- 1 から 100 までのランダムな整数を生成
- 入力値が小さいか大きいかを表示
- 一致したらメッセージを表示
クレートを使用して機能追加
Rust のクレートとはコンパイルの単位でコードの集まりです。cargo new
を実行してパッケージを作成すると実行バイナリのクレートが1つ作成されることになります。
ライブラリ用のプロジェクトで生成したライブラリクレートには、別のプログラムで使用するコードが含まれており連携して使用します。単独では実行できません。
乱数を発生させるために、Cargo.toml
に rand
クレートを追加します。
[dependencies]
rand = "0.8.5"
このプロジェクトを cargo build
します。すると、必要な依存関係を **https://crates.io/**から取得しコンパイルが行われます。
$ cargo build
Blocking waiting for file lock on package cache
Updating crates.io index
Blocking waiting for file lock on package cache
Blocking waiting for file lock on package cache
Compiling libc v0.2.132
Compiling cfg-if v1.0.0
Compiling ppv-lite86 v0.2.16
Compiling getrandom v0.2.7
Compiling rand_core v0.6.3
Compiling rand_chacha v0.3.1
Compiling rand v0.8.5
Compiling day_6_guessing_game v0.1.0
Finished dev [unoptimized + debuginfo] target(s) in 2m 59s
rand
クレートの提供する thread_rng
関数を使用して乱数を生成します。
let secret_number = rand::thread_rng().gen_range(1..101);
この gen_range
メソッドが使用している範囲表現は、開始..終了
という形式です。この表現での値は、下限値は含みますが上限値は含みません。そのため、上限を100とするために 101
と指定しています。
クレートとパッケージ
Rust のモジュールシステムをここで調べてみました。
要素 | 概要 |
---|---|
パッケージ | Cargoパッケージマネージャで管理されるクレートの集合 |
クレート | パッケージ内の個々の実行バイナリとライブラリ |
モジュール | 関数などの要素の論理的な階層 |
パス | 関数などの要素やモジュールの論理的な場所を示す名前 |
数値の比較
match
式と Ordering
列挙子を使って比較を行います。
Ordering
も enum
の1つで Less
, Greater
, Equal
の3つの列挙子を持っています。
そして、cmp
メソッドが比較した2つの値から Ordering
列挙型の列挙子を返します。
match式
は、Java で言うところの Case分のようなものですね。パターンを照合して合致したら、そのときの結果を返すというものです。
型の変換
Rust は強い静的型システムを持ち、型推論も行う言語です。
そのため、比較しようとしている以下の部分で文字列と数値の比較ができずエラーにこのままだとなってしまいます。
match guess.cmp(&secret_number)
guess
が文字列、secret_number
が数値型です。
そこで、guess
を数値型に変換を行う処理を追加します。
let guess: u32 = guess.trim().parse().expect("数値を入力してください");
ここでは、String
が持つ parse
メソッドを使用して数値変換を行っています。
変数のシャドーイング
Rust では既に宣言済みの変数と同じ名前の変数を新しく宣言することができます。
ここでは、guess
が繰り返し宣言されました。これを シャドーイング と呼びます。
このとき、新しく宣言された同一名の変数は、前の変数を覆い隠すような動作になります。
例:
fn main() {
let x = 1;
let x = x + 2;
let x = x * 3;
println!("The value of x is: {}", x);
}
このようなケースの場合、答えは 9
が表示されます。
覆い隠すということが分かれば、どのように x
に値が格納されていったか想像できますよね。
Day 7 のまとめ
今日は、機能からの続きで「数当てゲーム」を作りながら、言語仕様を見ていきました。
そして今日の1番の Lessons Learned は、知らない関数に出会ったら API リファレンスを見てみる、ってことです。
API へのたどり着き方は、クレートを見つけ、そこからの API リファレンスを見ていく、だと思いました。
- crates.io (https://crates.io/) から対象のクレートを探す
- 対象のクレート情報で表示されているAPI リファレンスのリンクをたどる
- 対象のメソッドを見つける
このような流れになるのかなと思いました。Rust に慣れないうちは、API リファレンスを見る頻度を増やそうと思います。
Discussion