Rust公式チュートリアル(第1章、第2章)

## はじめに
The Rust Programming Language 日本語版の勉強のために、**自分が大切だと思った箇所に装飾**を付けて記録を残しました。

この記事の内容は、以下記事の引用です。
引用元 : 
https://doc.rust-jp.rs/book-ja/ch01-00-getting-started.html

## 関数の種類
<font color="FireBrick">「マクロ」</font>とは、**コンパイル時に実行**される関数のこと。

println!でマクロ(コンパイル時に実行)を呼び出し、
println(!なし)でそのプログラムがコンピュータ上で処理を開始した際に呼ばれる関数の呼び出し。

とりあえず、「!」を使用すると、普通の関数ではなくマクロを読んでいるのだと把握していれば良いらしい。

## コンパイルと実行は個別のステップ
Rustプログラムを実行する前に、以下のように「rustc」コマンドを入力し、ソースファイルの名前を渡すことで、Rustコンパイラを使用してコンパイルしなければなりません。

```
$ rustc main.rs
```
コンパイルに成功後、Rustはバイナリの実行可能ファイルを出力します。

シェルで実行可能ファイルを見ることができます。

```
$ ls
main  main.rs
```
簡単なプログラムなら「rustc」でコンパイルするだけでも十分ですが、プロジェクトが肥大化してくると、オプションを全て管理し、自分のコードを簡単に共有したくなるでしょう。

そんなときに<font color="FireBrick">「Cargoツール」</font>を使います。

## Cargoツールとは
Rustのビルドシステム兼パッケージマネージャです。
ほとんどのRust使用者はこのツールを使用して、Rustプロジェクトの管理をしています。

Cargoは、コードのビルドやコードが依存しているライブラリのダウンロード、それらのライブラリのビルドなどの多くの仕事を扱ってくれるからです。

## cargoでプロジェクトを作成する
Cargoを使用して新しいプロジェクトを作成し、
元のHello,world!プロジェクトとどう違うかを見ていきましょう。

projectディレクトリに戻り、以下を実行してください。

```
$ cargo new hello_cargo --bin
$ cd hello_cargo
```
最初のコマンドは、**hello_cargoという新しいバイナリの実行可能ファイルを作成**しました。

cargo newに渡した「--bin」引数が、ライブラリとは対象的に実行可能なアプリケーションを作成します。

hello_cargoディレクトリに移動し、ファイルを列挙してください。
Cargoが２つのファイルと1つのディレクトリを生成してくれたことがわかるでしょう。

「Cargo.toml」ファイルと、中に「main.rs」ファイルがあるsrcディレクトリです。

また、.gitignoreファイルと共に、新しいGitリポジトリも初期化しています。

## Cargo.tomlはCargoの設定フォーマット
以下は、cargo newで生成される**Cargo.tomlの中身**です。
ファイル名: Cargo.toml

```
[package]
name = "hello_cargo"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]

[dependencies]
```

最初の行の[package]は、後の文がパッケージを設定していることを示すセクションヘッダーです。

その後の3行が、Cargoがプログラムをコンパイルするのに必要な設定情報をセットします。

名前、バージョン、誰が書いたかです。
Cargoは名前とEメールの情報を環境から取得するので、その情報が正しくなければ、今修正してそれから保存してください。

最後の行の[dependencies]は、プロジェクトの依存を列挙するためのセクションの始まりです。

Rustでは、<font color="FireBrick">パッケージのコードは「クレート」</font>として参照されます。

----

※**crate(クレート)**とは
**Rustプログラムの構成単位(コンパイルの単位)**のこと。

---
前のプロジェクトとCargoが生成したプロジェクトの違いは、Cargoが**src**ディレクトリにコードを配置し、最上位のディレクトリに**Cargo.toml**設定ファイルがあることです。

Cargoは、ソースファイルが**src**ディレクトリにあることを期待します。

プロジェクトの最上位のディレクトリは、READMEファイル、ライセンス情報、設定ファイル、あるいは、他のコードに関連しないもののためです。

Cargoを使用すると、プロジェクトを体系化する手助けをしてくれます。適材適所であり、全てがその場所にあるのです。

## Cargoプロジェクトをビルドし、実行する
さて、CargoでHello,world!プログラムをビルドし、実行する時の違いに目を向けましょう。

hello_cargoディレクトリから以下のコマンドを入力してプロジェクトをビルドしてください。

```
$ cargo build
   Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs
```
このコマンドは、カレントディレクトリではなく**「target/debug/hello_cargo」**に実行可能ファイルを作成します。

```
./target/debug/hello_cargo
```
全てが上手く行けば、上のコードで「Hello, world!」が端末に出力されるはずです。

初めて「cargo build」を実行すると、Cargoが最上位に新しいファイルを作成します。

**「Cargo.lock」**です。

このファイルは、自分のプロジェクトの依存の正確なバージョンを追いかけます。

このプロジェクトには依存がないので、ファイルはやや空っぽです。

Cargoが中身を管理してくれるので、<font color="FireBrick">絶対に「Cargo.lock」ファイルを手動で変更する必要はない</font>でしょう。

「cargo build」でプロジェクトをビルドし、「./target/debug/hello_cargo」で実行したばかりですが、**「cargo run」**を使用して、コードをコンパイルし、それから吐かれた**実行可能ファイルを全部1コマンドで実行**することもできます。

```
$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/hello_cargo`
Hello, world!
```
今回は、Cargoがhello_cargoをコンパイルしていることを示唆する出力がないことに注目してください。

Cargoはファイルが変更されていないことを推察したので、単純にバイナリを実行しました。

ソースコードの変更をしていたら、Cargoは実行前にプロジェクトを再ビルドし、こんな出力を目の当たりにしたでしょう。

```
$ cargo run
   Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.33 secs
     Running `target/debug/hello_cargo`
Hello, world!
```

## 「cargo build」と「cargo run」の違い
**「cargo build」**コマンドはプロジェクトのビルドをした後に
「./target/debug/hello_cargo」のように実行可能ファイルの実行が必要だが、
**「cargo run」**は**プロジェクトのビルドと一緒に実行可能ファイルの実行までも同時**にしてくれる！

Cargoは「cargo check」というコマンドで、
迅速にコードを確認し、コンパイルできることを確かめますが、**実行可能ファイルは生成しない**ようなコマンドも提供しています。

```
$ cargo check
   Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs
```
なぜ、実行可能ファイルが欲しくないのでしょうか？

しばしば、「cargo check」は「cargo build」よりも遥かに速くなります。

実行可能ファイルを生成する手順を飛ばすからです。

コードを書いている際に<font color="FireBrick">継続的に自分の作業を確認するのなら、「cargo check」を使用すると、その過程が高速化</font>されます。

そのため、多くのRust使用者は、プログラムを書く際に<font color="FireBrick">コンパイルできるか確かめるために定期的に「cargo check」を実行</font>します。

そして、実行可能ファイルを使用できる状態になったら「cargo build」を走らせるのです。

## Cargoのまとめ
- 「cargo build」か「cargo check」でプロジェクトをビルドできる
- プロジェクトのビルドと実行を1ステップ、「cargo run」でできる
- **ビルドの結果**をコードと同じディレクトリに保存するのではなく、Cargoは**「target_debug」**ディレクトリに格納する

## リリースビルドを行う
プロジェクトを最終的に<font color="FireBrick">リリース</font>する準備ができたら、
<font color="FireBrick">「cargo build --release」</font>を使用して、最適化を行ってコンパイルすることができます。

このコマンドは、**「target/debug」**ディレクトリではなく、**「target/release」**ディレクトリに実行可能ファイルを作成します。

最適化は、Rustコードの実行を速くしてくれますが、オンにするとプログラムをコンパイルする時間が延びます。

このため、２つの異なるプロファイルがあるのです。

頻繁に再ビルドをかけたい開発用と繰り返し再ビルドすることなくできるだけ高速に動いてユーザーにあげる最終的なプログラムをビルドする用です。

コードの実行時間をベンチマークするなら、
「cargo build --release」を確実に実行し、**「target/release」**の実行下方ファイルでベンチマークしてください。

## 新規プロジェクトの立ち上げ
ここでは、数あてゲームを実装しましょう。
プログラムは1から100までの乱数整数を生成します。
そしてプレーヤーに予想を入力するよう促します。

予想を入力したら、プログラムはその予想が小さすぎたか、大きすぎたかを出力します。

予想が当たっていれば、ゲームは祝福メッセージを表示し、終了します。

まずは、第一章で作成した**project**ディレクトリに行き、Cargoを使って新規プロジェクトを作成します。

```
$ cargo new guessing_game --bin
$ cd guessing_game
```
最初のコマンド「cargo new」は、プロジェクト名を第一引数にトリます(guessing_gameですね)。

**「--bin」**というフラグは、**Cargoにバイナリ生成プロジェクトを作成**させます。

2番目のコマンドで新規プロジェクトのディレクトリに移動します。
生成された**「Cargo.toml」**ファイルを見てください。

ファイル名: Cargo.toml

```
[package]
name = "guessing_game"
version = "0.1.0"
authors = ["名前 <you@example.com>"]

[dependencies]
```
第一章でも見かけたように、<font color="FireBrick">「cargo new」コマンドは「"Hello, world!"」プログラムを生成</font>します。

**「src/main.rs」**ファイルをチェックしてみましょう。

```
// ファイル名: src/main.rs

fn main() {
    println!("Hello, world!");
}
```
さて、この"Hello, world!"プログラムをコンパイルし、「cargo run」コマンドを使用して、以前と同じように動かしてみましょう。

```
$ cargo run
   Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
    Finished dev [unoptimized + debuginfo] target(s) in 1.50 secs
     Running `target/debug/guessing_game`
Hello, world!
```
**「run」**コマンドは、プロジェクトに迅速に段階を踏んで取り掛かる必要がある場合に有用であり、次のステップに進む前に各段階を急速にテストして、このゲームではそれを行います。

<font color="FireBrick">再度「src/main.rs」ファイルを開きましょう。
ここに全てのコードを書いていきます</font>。

## 予想を処理する
数あてプログラムの最初の部分は、ユーザー入力を求め、その入力を処理し、予期した形式になっていることを確認します。

手始めに、プレーヤーが予想を入力できるようにしましょう。
下記コードを**src/main.rs**に入力してください。
**▼ファイル名: src/main.rs**

```rs
use std::io;

fn main() {
    println!("Guess the number!");          // 数を当ててごらん

    println!("Please input your guess.");   // ほら、予想を入力してね

    let mut guess = String::new();

    io::stdin().read_line(&mut guess)
        .expect("Failed to read line");     // 行の読み込みに失敗しました

    println!("You guessed: {}", guess);     // 次のように予想しました: {}
}
```
**※注意**
Rustのソースコードでは、**コメント以外に日本語文字があるとコンパイルに失敗**することがあるらしい！

上記コードには、沢山の情報が詰め込まれていますね。

なので、行ごとに見ていきましょう。

ユーザー入力を受付け、結果を出力するためには<font color="FireBrick">「io(入/出力)」</font>ライブラリをスコープに導入する必要があります。

ioライブラリは、標準ライブラリ(stdとしても知られています)に存在します。

```rs
use std::io;
```
デフォルトでは、<font color="FireBrick">preludeに存在するいくつかの型のみ使えます」</font>。

preludeにない場合は、use文で明示的にその型をスコープに導入する必要があります。

**※prelude(プレリュード)とは**
「std::prelude」モジュールに含まれるものは、**すべてのRustプログラムで自動的にインポート**される。

よく使うものをすべて手動でインポートする必要をなくすため。

「std::io」ライブラリを使用することで、ユーザー入力を受け付ける能力などの実用的な機能を多く使用することができます。

第一章で見たとおり、**main関数がプログラムへのエントリーポイント（スタート地点）**になります。

```
fn main() {
```
fn構文が関数を新しく宣言し、カッコの()は引数がないことを示し、波括弧の{が関数本体のスタート地点になります。

また、「println!」は文字列を画面に表示するマクロ(コンパイル時に実行)です。

```rs
println!("Guess the number!");
println!("Please input your guess.");
```
このコードは、このゲームが何かを出力し、ユーザに入力を求めています。

## 値を変数に保持する
次に、ユーザー入力を保持する場所を作りましょう。

```rs
let mut guess = String::new();
```
さあ、プログラムが面白くなってきましたね。
このたった１行でいろんなことが起きています。

これが**let文**であることに注目してください。
これを使用して**変数**を生成していきます。

こちらは別の例です。

```rs
let foo = bar;
```
この行では、fooという名前の新しい変数を作成し、barという値に束縛しています。

<font color="FireBrick">Rustでは、変数は標準で普遍(変更不可)</font>です。

この概念について詳しくは第三章で議論します。

以下の例には、
<font color="FireBrick">変数名の前に「mut」をつけて変数を可変にする方法</font>が示されています。

```rs
let foo = 5; // immutable
let mut bar = 5; // mutable
```
数あてゲームのプログラムに戻りましょう。
さあ、let mut guessがguessという名前の可変変数を導入するとわかりましたね。

イコール記号の反対側には、変数guessが束縛される値があります。

この値は**「String::new」**関数の呼び出し結果であり、この関数は、**String型のオブジェクトを返します**。

**String**型は、標準ライブラリによって提供される文字列型で、サイズ可変、UTF-8エンコードされたテキスト破片になります。

**「::new」**行にある<font color="FireBrick">「::」</font>という記法は、<font color="FireBrick">newがString型の関連関数</font>であることを表しています。

<font color="FireBrick">関連関数</font>とは、<font color="FireBrick">String型の特定のオブジェクトよりも型(この場合はString)に対して実装された関数のこと</font>であり、静的メソッドと呼ばれる言語もあります。

<font color="FireBrick">「○○::メソッド」のように、○○に対して作られたメソッド</font>を意味するよ。

ここで言えば、**「String型」に用意されたnew()メソッドのような関係性**だよ。

このnew関数は、新しく空の文字列を生成します。
new関数は、いろんな型に見られます。

なぜなら、何らかの新規値を生成する関数によってありふれた名前だからです。

まとめると、「let mut guess = String::new();」という１行は、現在**新たに空のStringオブジェクトに束縛されている可変変数を作っている**わけです。ふう！

プログラムの１行目で、**「use std::io」として、標準ライブラリから入出力機能を取り込んだ**ことを思い出してください。

今度は、**io型のstdin関連関数**を呼び出しましょう。

```rs
io::stdin().read_line(&mut guess)
    .expect("Failed to read line");
```
仮に<font color="FireBrick">、プログラムの冒頭で**「use std::io」としていなければ、この関数呼び出しは、「std::io::stdin」と記述していたでしょう</font>。

この**stdin関数は、「std::io::stdin」オブジェクトを返し**、この型は、ターミナルの標準入力への<font color="FireBrick">ハンドル(onClickなどのようなハンドラーに紐付ける処理と同じ意義:発火された際にどういう処理をするのかを決定したもの:処理自体を指す)</font>を表す型になります。

その次のコード、「.read_line(&mut guess)」は、標準入力ハンドルの「read_line」メソッドを呼び出して、ユーザからの入力を受け付けます。

また、**read_lineメソッドに対して、「&mut guess」という引数を１つ渡しています**ね。

<font color="FireBrick">read_lineメソッドの仕事は、ユーザーが標準入力したもの全てを取り出し、文字列に格納すること</font>なので、**格納する文字列を引数として受け取り**ます。

この文字列引数は、可変である必要があります。
メソッドがユーザ入力を追加して、文字列の中身を帰れるようにということですね。

<font color="FireBrick">「&」</font>という記号は、<font color="FireBrick">この引数が参照であることを表し</font>、これのお陰で、データを複数回メモリにコピーせずとも、コードの複数箇所で同じデータにアクセスできるようになります。

**参照は複雑な機能であり、とても安全かつ簡単に参照を使うことができることは、Rustの主要な利点の１つ**でもあります。

そのような詳細を知らなくても、このプログラムを完成させることはできます。

現時点では、**変数のように参照も標準で普遍である**ことを知っておけばいいでしょう。

ゆえに、「&guess」と書くのではなく、**「&mut guess」と書いて、可変にする必要**があるのです。

## Results型で失敗の可能性を扱う
まだこの行は終わりではありませんよ。
ここまでに議論したのはテキストでは１行ですが、コードとしての論理行としてはまだ序盤の部分でしかないのです。

２番目の部分は**「.expect()」**メソッドです。

```rs
.expect("Failed to read line");
```
.foo()という記法で、メソッドを呼び出す時、改行と空白で長い行を分割するのがしばしば賢明です。

今回の場合、こう書くこともできますよね。

```rs
io::stdin().read_line(&mut guess).expect("Failed to read line");
```
しかし、長い行は読みづらいものです。
なので、分割しましょう。

また、以前も述べたように、**read_lineメソッドは、渡された文字列にユーザが入力したものを入れ込むだけでなく、値も返します**。(今回は**io::Result**です)

RustにはResultと名のついた型が、標準ライブラリにたくさんあります。

この<font color="FireBrick">Result型は、列挙型であり、普通enum(イーナム)</font>と呼ばれます。

**列挙型とは、固定された種類の値を持つ型のこと**であり、**それらの値は、enumの列挙子**と呼ばれます。

enumについては、第六章で詳しく解説します。

<font color="FireBrick">Result型に関しては、列挙子はokかErr</font>です。

**ok列挙子**は、**処理が成功**したことを表し、中に生成された値を保持します。

**Err列挙子**は、**処理が失敗**したことを意味し、Errは、処理が失敗した過程や理由などの情報を保有します。

これら**Result型の目的は、エラー処理の情報をコード化すること**です。

Result型の値も、他の型同様、メソッドが定義されています。

<font color="FireBrick">io::Resultオブジェクトには、呼び出し可能なexpectメソッド</font>があります。

この**ip::ResultオブジェクトがErrの場合、ecpectメソッドはプログラムをクラッシュさせ、引数として渡されたメッセージを表示**します。

**read_lineメソッドがErrを返したら、おそらく根底にあるOSによるエラーに起因**するでしょう。

この**io::Resultオブジェクトがokの値の場合、expectメソッドはok列挙子が保持する返り値を取り出して、ただその値を返すので、これを使用することができます**。

今回の場合、<font color="FireBrick">その返り値とは、ユーザが標準入力に入力したデータのバイト数</font>になります。

もし、**expectメソッドを呼び出さなかったら、コンパイルは通るものの、警告が出る**でしょう。

## println!マクロのプレースホルダーで値を出力する
閉じ並みカッコを除けば、ここまでに追加されたコードのうち議論すべきものは残り１行です。

```rs
println!("You guessed: {}", guess);
```
この行は、**ユーザー入力を保存した文字列の中身を出力**します。

<font color="FireBrick">1組の波括弧{}は、プレースホルダーの役割</font>を果たします。

**{}は、値を所定の場所に保持する小さなカニのはさみ**と考えてください。

波括弧を使って１つ以上の値を出力できます。
最初の波括弧の組は、フォーマット文字列のあとに列挙された最初の値に対応し、2組目は2つ目の値、、そんな感じで続いてきます。

1回のprintln!の呼び出して、複数の値を出力するコードは以下のようになります。

```rs
let x = 5;
let y = 10;

println!("x = {} and y = {}", x, y);
```
このコードは、「x = 5 and y = 10」と出力するでしょう。

## 最初の部分をテストする
数当てゲームの最初の部分をテストしてみましょう。
「cargo run」でプログラムを走らせてください。

```
$ cargo run
   Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
    Finished dev [unoptimized + debuginfo] target(s) in 2.53 secs
     Running `target/debug/guessing_game`
Guess the number!
Please input your guess.
6
You guessed: 6
```
ここまでで、ゲームの最初の部分は完成になります。
キーボードからの入力を受付、出力できています。

## 秘密の数字を生成する
次に、ユーザが数当てに挑戦する秘密の数字を生成する必要があります。

ゲームを何回も楽しめるように、毎回この秘密の数字は変わるべきです。

ゲームが難しくなりすぎないように、1から100までの乱数を使用しましょう。

Rustの標準ライブラリには、乱数機能はまだ含まれていません。
ですが、実はRustの開発チームがrandクレートを用意してくれています。

## クレート(Rustコードのパッケージ)を使用して機能を追加する
クレートはRustコードのパッケージであることを思い出してください。

私達が**ここまで作ってきたプロジェクト**は、**バイナリクレートであり、これは実行可能形式**になります。

<font color="FireBrick">randクレートはライブラリクレートであり、他のプログラムで使用するためのコードが含まれています</font>。

外部クレートを使用する部分は、Cargoがとても輝くところです。
randを使ったコードを書く前に、**Cargo.toml**ファイルを編集して、**randクレートを依存ファイルとして取り込む**必要があります。

[dependencies]セクションヘッダの一番下に追記しましょう。

**▼ファイル名: Cargo.toml**

```rs
[dependencies]
rand = "0.3.14"
```
**Cargo.toml**ファイルにおいて、ヘッダに続くものは全て、他のセクションが始まるまで続くセクションの一部になります。

<font color="FireBrick">[dependencies]セクションは、"プロジェクトが依存する外部クレート"と"必要するバージョン"を記述するところ</font>です。

ここでは、randクレートでセマンティックバージョン指定しには0.3.14を指定します。

Cargoは、バージョンナンバー記述の標準規格であるセマンティックバージョニングを理解します。

0.3.14という数字は、実際には^0.3.14<font color="FireBrick">(^:互換性があるという意味)</font>の省略記法で、これは**「バージョン0.3.14と互換性のある公開APIを持つ任意のバージョン」**を意味します。

さて、コードは一切変えずに、以下のようにプロジェクトをビルドしましょう。

```
$ cargo build
```
今や、外部依存を持つようになったので、Cargoは**レジストリ**から最新バージョンを拾ってきます。

**レジストリ**とは、**Crates.ioデータのコピー**です。

<font color="FireBrick">Crates.ioとは、Rustのエコシステムにいる人間が、他の人が使えるように自分のオープンソースのRustプロジェクトを投稿する場所</font>です。

**レジストリの更新後、Cargoは[dependencies]セクションをチェックし、まだ取得していないクレートを全部ダウンロード**します。

今回の場合、randしか依存ファイルには列挙していませんが、Cargoはlibc(標準ライブラリ)のコピーも拾ってきます。

randクレートがlibcに依存しているからです。
クレートのダウンロード完了後、コンパイラは依存ファイルをコンパイルし、依存が利用可能な状態でプロジェクトをコンパイルします。

何も変更せず即座にcargo buildコマンドを走らせたら、Finished行を除いて何も出力されないでしょう。

## Cargo.lockファイルで再現可能なビルドを保証する
Cargoは、プログラムが自分のコードを更新する度に同じ生成物を再構成することを保証してくれるメカニズムを備えています。

Cargoは、プログラマが示唆するまで、指定したバージョンの依存のみを使用します。

例として、randクレートの次週のバージョン0.3.15が登場し、重要なバグ修正がなされているけれども、自分のコードを破壊してしまう互換性破壊があった場合はどうなるでしょうか？

この問題に対する回答は**Cargo.lock**ファイルであり、このファイルは初めて**cargo buildコマンドを走らせたときに生成**され、現在**guessing_game**ディレクトリに存在しています。

プロジェクトを初めてビルドする際に、Cargoは判断基準に合致するよう全ての依存バージョンを計算し、**Cargo.lock**ファイルに記述します。

次にプロジェクトをビルドする際には、Cargoは**Cargo.lock**ファイルが存在することを確かめ、再度バージョンの計算の作業を行うのではなく、そこに指定されている場＾ジョンを使用します。

このことにより、自動的に再現可能なビルドを構成出来るのです。
つまり、明示的にアップグレードしない限り、プロジェクトが使用するバージョンは0.3.14に保たれるのです。

**Cargo.lock**ファイルのおかげでね。

## クレートを更新して新バージョンを取得する
クレートを**本当に**アップグレードする必要が出てきたら、Cargoは別のコマンド**(update)**を提供します。

これは、**Cargo.lock**ファイルを無視して、**Cargo.toml**ファイル内の全ての指定に合致する最新バージョンを計算します。

それらがうまくいったら、Cargoはそれらのバージョンを**Cargo.lock**ファイルに記述します。

しかし標準でCargoは、0.3.0より大きく、0.4.0未満のバージョンのみを検索します。

randクレートの新バージョンが2つリリースされていたら、cargo updateコマンドを走らせたときに以下のようなメッセージが出力されます。

```
$ cargo update
    Updating registry `https://github.com/rust-lang/crates.io-index`
    (レジストリ`https://github.com/rust-lang/crates-io-index`を更新しています)
    Updating rand v0.3.14 -> v0.3.15
    (randクレートをv0.3.14 -> v0.3.15に更新しています)
```
この時点で、**Cargo.lock**ファイルに書かれている現在使用しているrandクレートのバージョンが0.3.15になっていることにも気づくでしょう。

randのバージョン0.4.0または0.4.xシリーズのどれかを使用したかったら、代わりに**Cargo.toml**ファイルを以下のように更新しなければならないでしょう。

```[dependencies]

rand = "0.4.0"
```
次回、cargo buildコマンドを走らせたら、Cargoは利用可能はトレーとのレジストリを更新し、randクレートの必要条件を指定した新しいバージョンに従って再評価します。

Cargoのおかげでライブラリはとても簡単に再利用ができるので、数多くのパッケージから構成された小規模のプロジェクトを書くことができます。

## 乱数を生成する
**Cargo.toml**にrandクレートを追加したので、randクレートを使用開始しましょう。

次のステップは、*src/main.rs***ファイルを更新することです。

**▼ファイル名: src/main.rs**

```rs
// extern crate:ライブラリと同じ名前のモジュールにインポート
extern crate rand;

use std::io;
use rand::Rng;

fn main() {
    println!("Guess the number!");

    // rand::thread_rng():これから使う特定の乱数生成器を返す
   //.gen_range():2つの引数の間の乱数を生成。下限値を含み、上限値を含まない
    let secret_number = rand::thread_rng().gen_range(1, 101);

    println!("The secret number is: {}", secret_number);    //秘密の数字は次の通り: {}

    println!("Please input your guess.");

    let mut guess = String::new();

    io::stdin().read_line(&mut guess)
        .expect("Failed to read line");

    println!("You guessed: {}", guess);
}
```
まずコンパイラにrandクレートを外部依存として使用することを知らせる行を追加します。

これにより、use randを呼ぶのと同じ効果が得られるので、randクレートをrand::という接頭辞をつけて呼び出せるようになりました。

次に、別のuse行を追加しています。
**「use rand::Rng」**ですね。

Rngトレイトは乱数生成器が実装するメソッドを定義しており、このトレイト(第10章で解説)がスコープにないと、メソッドを使用できないのです。

また、途中2行追加もしています。
**「rand::thred_rng」**関数は、**これから使う特定の乱数生成器を返してくれます**。

次に、この**乱数生成器の「gen_range」メソッド**を呼び出しています。

このメソッドは、use rand::Rng文でスコープに導入したRngトレイトで定義されています。

<font color="FireBrick">「gen_range」メソッドは、２つの数字を引数に取り、それらの間の乱数を生成</font>してくれます。

範囲は下限値を含み、上限値を含まないため、1と101と指定しないと、1から100の範囲の数字は得られません。

コードに追加した2行目は、秘密の数字を出力してくれます。
これは、プログラムを開発中にはテストするのに役立ちますが、最終盤からは削除する予定です。

プログラムがスタートと同時に答えを出力すると、げーむになりませんからね。

試しに何回かプログラムを走らせてみてください

```rs
$ cargo run
   Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
    Finished dev [unoptimized + debuginfo] target(s) in 2.53 secs
     Running `target/debug/guessing_game`
Guess the number!                         (何回も出ているので、ここでは和訳は省略します)
The secret number is: 7
Please input your guess.
4
You guessed: 4
$ cargo run
     Running `target/debug/guessing_game`
Guess the number!
The secret number is: 83
Please input your guess.
5
You guessed: 5
```
**毎回異なる乱数が出て、その数字はすべて1から100の範囲になるはず**です。よくやりました！

## 予想と秘密の数字を比較する
今や、ユーザー入力と乱数生成ができるようになったので、比較することができますね。

以下のコードは現状ではコンパイルできないことに注意してください。

**▼ファイル名: src/main.rs**

```rs
extern crate rand;

use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {

    // ---snip---

    println!("You guessed: {}", guess);

    match guess.cmp(&secret_number) {
        Ordering::Less => println!("Too small!"),       //小さすぎ！
        Ordering::Greater => println!("Too big!"),      //大きすぎ！
        Ordering::Equal => println!("You win!"),        //やったね！
    }
}
```
最初の新しい点は、別のuseb文です。
これで、<font color="FireBrick">「std::cmp::Ordering(2値を比較したときに発生しうる3種類の結果->Less, Greater, Equal)」</font>という型を標準ライブラリからスコープに導入しています。

Resultと同じく、Orderingもenumです。
ただ、**Orderingの列挙子は、Less, Greater, Equal**です。

Less、Greater、Equalです。これらは、2値比較した時に発生しうる3種類の結果です。

```rs
match guess.cmp(&secret_number) {
    Ordering::Less => println!("Too small!"),
    Ordering::Greater => println!("Too big!"),
    Ordering::Equal => println!("You win!"),
}
```
それから、一番下に新しく5行追加してOrdering型を使用しています。

<font color="FireBrick">cmpメソッドは、2値を比較し、比較出来るものに対してなら何に対しても呼び出せます</font>。

このメソッドは、比較したいものへの参照を取ります。
ここでは、guess変数とsecret_number変数を比較しています。

それからこのメソッドはuse文でスコープに導入したOrdering列挙型の値を返します。

match式を使用して、guess変数とsecret_numberをcmpに渡して帰ってきたOrderingの列挙子に基づき、次の動作を決定しています。

**match式**は、**複数のアーム(腕)**からできています。
一つのアームは、パターンとそのパターンにmatch式の冒頭で与えられた値がマッチしたときに走るコードから構成されています。

Rustは、matchに与えられた値を取り、各アームのパターンを順番に照合していきます。

match式とパターンは、コードを書く際に出くわす様々なシチュエーションを表現してくれ、全てのシチュエーションに対処していることを保証するのを手助けしてくれるRustの協力な機能です。

ここで使われているmatch式でどんなことが起こるのかの例をじっくり観察してみましょう。

例えば、ユーザは50と予想し、ランダム生成された秘密の数字は今回38だったとしましょう。

コードが50と38を比較すると、cmpメソッドは「Ordering::Greater」を返します。

50は38より大きいからですね。

match式に「Ordering::Greater」が与えられ、各アームのパターンを吟味し始めます。

「Ordering::Greater」は見事にOrdering::Greaterとマッチします。

このアームに紐づけられたコードが実行され、画面にToo big!が表示されます。 

これでmatch式の実行は終わりになります。

この筋書きでは、最後のアームと照合する必要はもうないからですね。

ところが上記は**まだコンパイルが通りません。**

```rs
$ cargo build
   Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
error[E0308]: mismatched types          (型が合いません)
  --> src/main.rs:23:21
   |
23 |     match guess.cmp(&secret_number) {
   |                     ^^^^^^^^^^^^^^ expected struct `std::string::String`, found integral variable
   |                                    (構造体`std::string::String`を予期したけど、整数型変数が見つかりました)
   |
   = note: expected type `&std::string::String`
   = note:    found type `&{integer}`

error: aborting due to previous error   (先のエラーのため、処理を中断します)
Could not compile `guessing_game`.      (`guessing_game`をコンパイルできませんでした)
```
このエラーの核は、**型の不一致**があると言っています。
Rustには、強い静的型システムがあります。

しかし、型推論にも対応しており、「let guess = String::now()」と書いた時、コンパイラはguessがString型であるはずと推論してくれ、その方を明示させられることはありませんでした。

一方で、**secret_number変数は数値型**です。
1から100を表すことができる数値型はいくつかあります。

**「i32」は32ビットの数字**、**「u32」は32ビットの非負数字(負でない数字)**、**「i64」は64ビットの数字**などです。

<font color="FireBrick">Rustでの標準は、i32型</font>であり、型情報をどこかに追加して、コンパイルに異なる数値型だと推論させない限り、secret_numberの型はこれになります。

エラーの原因は、Rustでは、文字列と数値型を比較できないことです。

究極的には、プログラムが入力として読み込むString型を現実の数値型に比較し、予想と数値として比較できるようにしたいわけです。

これは、以下の2行をmain関数の本体に追記することでできます。

**▼ファイル名: src/main.rs**

```ｒｓ

// --snip--

    // ★基本的に、標準入出力はStringで行う
    let mut guess = String::new();

    io::stdin().read_line(&mut guess)
        .expect("Failed to read line");

    let guess: u32 = guess.trim().parse()
        .expect("Please type a number!");                 //数値を入力してください！

    println!("You guessed: {}", guess);

    match guess.cmp(&secret_number) {
        Ordering::Less => println!("Too small!"),
        Ordering::Greater => println!("Too big!"),
        Ordering::Equal => println!("You win!"),
    }
}
```
その2行とは、

```rs
let guess: u32 = guess.trim().parse()
    .expect("Please type a number!");
```
guessという名前の変数を生成しています。
あれ、でもすでにプログラムにはguessという名前の変数があります。

確かにありますが、<font color="FireBrick">Rustでは新しい値でguessの値を覆い隠すことが許されている</font>のです。

この機能は、値を別の型に変換したいシチュエーションでよく使われます。

シャドーイングのおかげで、別々の変数を２つ作ることなくguessという変数名を再利用できます。

guessを**「guess_trim().parse()」**という式に束縛しています。

この式中のguessは、入力が入ったString型の元々のguessを指しています。

<font color="FireBrick">Stringオブジェクトのtrimメソッドは、両端の空白を全て除去</font>します。

u32型は、数字しか含むことができませんが、ユーザはread_lineの処理を終えるために**エンター**を押さなければなりません。

ユーザがエンターを押したら、改行文字が文字列に追加されます。

trimメソッドは「\n」を削除するので、ただの数字になります。

また、<font color="FireBrick">文字列のparseメソッドは文字列を解析して、何らかの数値にします</font>。

いろんな数値型を解析できるので、「let guess: u32」としてコンパイラに私達が求めている型をズバリ示唆する必要があります。

guessの後のコロン(:)がコンパイラに変数の型を注釈する合図です。

Rustには、組み込みの数値型がいくつかあります。

なお、**parseメソッドの呼び出しはエラーになりやすい**です。

失敗する可能性があるので、**parseメソッドは、Result型を返します**。

今回もexpectメソッドを使用して、Result型を同じように扱います。

もし、文字列から数値を生成できなかったために、parseメソッドがResult型のErr列挙子を返したら、 expectメソッドの呼び出しは、ゲームをクラッシュさせ、与えたメッセージを表示します。 

もし、parseメソッドが文字列の数値への変換に成功したら、Result型のok列挙子を返し、expectメソッドはok値から必要な値を返してくれます。

さあ、プログラムを走らせましょう！

```
$ cargo run
   Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
    Finished dev [unoptimized + debuginfo] target(s) in 0.43 secs
     Running `target/debug/guessing_game`
Guess the number!
The secret number is: 58
Please input your guess.
  76
You guessed: 76
Too big!
```
いいですね！
予想の前にスペースを追加したにも関わらず、プログラムはちゃんとユーザが76と予想したことを導き出しました。

ここまでで大方ゲームはうまく動くようになりましたが、まだユーザが１回しか予想できません。

ループを追加して、その部分を変更しましょう。

## ループで複数回の予想を可能にする
loopキーワードは、無限ループを作り出します。
これを追加して、ユーザが何回も予想できるようにしましょう。

**▼ファイル名: src/main.rs**

```rs
// --snip--

    println!("The secret number is: {}", secret_number);

    loop {
        println!("Please input your guess.");

        // --snip--

        match guess.cmp(&secret_number) {
            Ordering::Less => println!("Too small!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal => println!("You win!"),
        }
    }
}
```
見てわかる通り、予想入力部分以降をループに入れ込みました。

ループ内の行にインデントを追加するのを忘れないようにして、またプログラムを走らせてみましょう。

新たな問題が発生したことに注目してください。
プログラムが教えたとおりに動作しているため、永遠に予想入力を求め、ユーザが終了できません。

ユーザは、ctrl + cでいつでもプログラムを強制終了できます。

しかし、「予想と秘密の数字を比較する」節のparseメソッドに関する議論で触れたように、この貪欲なモンスターを回避する別の方法があります。

**ユーザが数字以外の答えを入力すれば、プログラムはクラッシュする**のです。

```terminal
$ cargo run
   Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
    Finished dev [unoptimized + debuginfo] target(s) in 1.50 secs
     Running `target/debug/guessing_game`
Guess the number!
The secret number is: 59
Please input your guess.
45
You guessed: 45
Too small!
Please input your guess.
60
You guessed: 60
Too big!
Please input your guess.
59
You guessed: 59
You win!
Please input your guess.
quit
thread 'main' panicked at 'Please type a number!: ParseIntError { kind: InvalidDigit }', src/libcore/result.rs:785
(スレッド'main'は'数字を入力してください！: ParseIntError { kind: InvalidDigit }', src/libcore/result.rs:785でパニックしました)
note: Run with `RUST_BACKTRACE=1` for a backtrace.
(注釈: `RUST_BACKTRACE=1`で走らせるとバックトレースを見れます)
error: Process didn't exit successfully: `target/debug/guess` (exit code: 101)
(エラー: プロセスは予期なく終了しました)
```
quitと入力すれば、実際にゲームを終了できるわけですが、別に他の数字以外の入力でもそうなります。

しかしながら、これは最低限と言えるでしょう。
<font color="FireBrick">正しい数字が予想されたら、自動的にゲームが停止してほしい</font>わけです。

## 正しい予想をした後に終了する
break文を追加して、ユーザが勝った時にゲームが終了するようにプログラムしましょう。

**▼ファイル名: src/main.rs**

```rs
// --snip--

        match guess.cmp(&secret_number) {
            Ordering::Less => println!("Too small!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal => {
                println!("You win!");
                break;
            }
        }
    }
}
```
break文の1行をYou win!の後に追記することで、ユーザが秘密の数字を正確に予想した時に、プログラムはループを抜けるようになりました。

ついでに、**ループを抜けることは、プログラムを終了することを意味**します。

ループがmain関数の最後の部分だからです。

## 不正な入力を処理する
さらにゲームの振る舞いを改善するために、ユーザが数値以外を入力した時にプログラムをクラッシュさせるのではなく、非数値を無視してユーザが数当てゲームを続けられるようにしましょう。

これは、guessがString型からu32型に変換される行を改変することで達成できます。

**▼ファイル名: src/main.rs**

```rs
// --snip--

io::stdin().read_line(&mut guess)
    .expect("Failed to read line");

let guess: u32 = match guess.trim().parse() {
    // num:成功した場合の値を格納
    Ok(num) => num,
    // _:包括値。どんな値でもErrにマッチさせることができる
    Err(_) => continue,
};

println!("You guessed: {}", guess);

// --snip--
```
**expextメソッドの呼び出しからmatch式に切り替える**ことは、**エラーでクラッシュする動作からエラー処理を行う処理に変更する一般的な手段**になります。

<font color="FireBrick">parseメソッドは、Result型を返し、ResultはOkかErrの列挙子を取りうる列挙型である</font>ことを思い出してください。

ここではmatch式を使っています。
cmpメソッドのOrderingという結果のような感じですね。

parseメソッドは、文字列から数値への変換に成功したら、結果の数値を保持するOk値を返します。

このOk値は、最初のアームのパターンにマッチし、このmatch式はparseメソッドが生成し、Ok値に格納したnumの値を返すだけです。

その数値が最終的に、生成している新しいguess変数としてほしい場所に存在します。

parseメソッドは、文字列から数値への変換に**失敗**したら、エラーに関する情報を多く含むErrを返します。

このErr値は、最初のmatchアームのOk(num)というパターンにはマッチしないものの、2番目のアームのErr(_)というパターンにはマッチするわけです。

この**「_」**は、**包括値**です。
この例では、保持している情報がどんなものでもいいから全てのErr値にマッチさせたいと宣言しています。

したがって、プログラムは2番目のアームのコードを実行し(continue)これは、loopの次のステップに移り、再度予想入力を求めるようプログラムに指示します。

故に実質的には、プログラムはparseメソッドが遭遇しうる全てのエラーを無視するようになります。

さて、プログラムのすべてがうまく予想通りに動くはずです。

```terminal
$ cargo run
   Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
     Running `target/debug/guessing_game`
Guess the number!
The secret number is: 61
Please input your guess.
10
You guessed: 10
Too small!
Please input your guess.
99
You guessed: 99
Too big!
Please input your guess.
foo
Please input your guess.
61
You guessed: 61
You win!
```
素晴らしい！
最後にひとつまみ変更を加えて、数当てゲームを完了しましょう。

プログラムが未だに秘密の数字を出力していることを思い出してください。

テスト中はうまく動くけど、ゲームを台無しにしてしまいます。
秘密の数字を出力するprintln!を削除しましょう。

**▼ファイル名: src/main.rs**

```rs
extern crate rand;

use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {
    println!("Guess the number!");

    let secret_number = rand::thread_rng().gen_range(1, 101);

    loop {
        println!("Please input your guess.");

        let mut guess = String::new();

        io::stdin().read_line(&mut guess)
            .expect("Failed to read line");

        let guess: u32 = match guess.trim().parse() {
            Ok(num) => num,
            Err(_) => continue,
        };

        println!("You guessed: {}", guess);

        match guess.cmp(&secret_number) {
            Ordering::Less => println!("Too small!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal => {
                println!("You win!");
                break;
            }
        }
    }
}
```

## まとめ
ここまでで、数当てゲームの構築に成功しました！