小さなプロジェクトに取り組んでRustを知ろう! Rustの基本概念を実際の例で示します。 let
、 match
、メソッド、関連関数、サードパーティライブラリの接続などについて学びます。 ゲームを推測するという古典的なタスクを実現しています。
- プログラムは1から100までの乱数を生成します。
- その後、彼はプレイヤーに推測を入力するように頼みます。
- その後、プログラムはプレーヤーに通知します。
- 彼が数字を推測したら、ゲームは終了します
- そうでない場合:
- 書き込み、推測された数よりも少ないか、推測された数より多い。
- ステップ2に進みます。
新しいプロジェクトを作成する
新しいプロジェクトを作成するには:
$ cargo new guessing_game --bin $ cd guessing_game
最初のcargo new
コマンドは、プログラムの名前( guessing_game
)を最初の引数として受け取ります。 --bin
は、(ライブラリではなく)プログラムを作成するためのプロジェクトを準備するようCargoに指示します。 プロジェクト構成ファイル-Cargo.tomlにあるものを見てみましょう
[package] name = "guessing_game" version = "0.1.0" authors = ["Your Name <you@example.com>"] [dependencies]
Cargoがシステムから受け取った作成者情報が正しくない場合は、構成ファイルを修正して保存します。 デフォルトでは、新しいプロジェクトには「Hello、world」が含まれています。
src / main.rs
fn main() { println!("Hello, world!"); }
プログラムをビルドして実行しましょう:
$ 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
コマンドは、コンパイル、ビルド、起動の各フェーズを順番に繰り返すことが多い場合に非常に役立ちます。
推測処理
プログラムの最初の部分では、ユーザーに推測を入力し、入力を処理して、正しいことを確認します。 まず、ユーザーが推測を入力できるようにします。以降、すべての変更はsrc/main.rs
に対して行われsrc/main.rs
。
// stdout 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); }
コードには多くの情報が含まれているため、徐々に検討してください。 入力された推測をユーザーから受け取り、stdoutで推測するには、 io
ライブラリをグローバルスコープに追加する必要があります 。 io
は、標準ライブラリ(以下std
ます)の一部です。
use std::io;
デフォルトでは、Rustはプログラムスコープにいくつかのタイプのみをもたらします( prelude
)。 prelude
必要なタイプがない場合は、 use
ステートメントを記述してスコープに手動で追加する必要があります。 std::io
を使用すると、ユーザー入力を読み取る機能など、入出力( IO )を操作するための多くの機能が提供されます。 main
関数(CおよびC ++など)は、プログラムへのエントリポイントです。
fn main() {
fn
使用すると、新しい関数を宣言できます。 ()
は、関数がパラメーターを受け入れないことを示し、 {
は関数の本体の前にあります。 println!
-コンソールに文字列を表示するマクロ( macro
):
println!("Guess the number!"); // . println!("Please input your guess.");
変数に値を保存します
次に、ユーザー入力が保存される場所を作成します。
let mut guess = String::new();
変数を作成するために必要なlet
ステートメントに注意してください。 それは可能です。
let foo = bar;
コードはfoo
という変数を作成し、 bar
の値をバインドしbar
。 Rustでは、デフォルトで変数は不変です。 それらを可変にするには、 let
隣の変数名にmut
を追加します。
let foo = 5; // (immutable) let mut bar = 5; // mutable()
let mut guess
で可変のguess
変数が作成let mut guess
ことがわかりました。 =
記号の右側は、 guess
バインドする値guess
これは、新しい文字列を返す関数であるString::new
を呼び出した結果です。 String
は、成長できる文字列型(C ++のstring
およびJavaのStringBuilder
と同様)で、 UTF-8エンコードされたテキストを含みます。 ::
in ::new
は、 new
がString
型の関連関数であることを示します。 関連付けられた関数は、型、この場合はString、および型の特定のインスタンスに実装されます。 C ++などの一部の言語は、このような関数の静的メソッドを呼び出します。 new
関数は、新しい空のString
インスタンスを作成します。 new
、あるタイプの新しい値を作成する関数を示すために使用されるため、多くのタイプで実装されていることがわかります。 まとめると: let mut guess = String::new();
新しい空のString
インスタンス(空の文字列)にバインドされる新しい可変変数を作成しました。 use std::io
をuse std::io
してIOを操作use std::io
関数を含めました。 次に、関連する関数stdin
呼び出します。
io::stdin().read_line(&mut guess) .expect("Failed to read line");
プログラムの最初にuse std::io
を記述しなかった場合、 std::io::stdin
形式でこの関数の呼び出しを記述できます。 stdin
関数は、 標準入力の ハンドルを表す型であるstd::io::Stdin
インスタンスを返します 。 これはユーザーのキーボードです。 コードの次の部分である.read_line(&mut guess)
、受信したばかりのポインター( handle )でread_line
を呼び出して、ユーザー入力を読み取るためのstdin
を呼び出します。 また、単一の引数&mut guess
も送信します。 read_line
は、ユーザーからstdin
入ってくるものを受け取り、この入力をストリングに入れます。したがって、ストリング変数へのリンクを受け入れます。 メソッドがユーザー入力を追加してこの文字列の値を変更できるように、この文字列引数は可変である必要があります。 &
は、引数( &mut guess
)がコードの異なる部分が同じデータ領域に値をそのデータ領域から何度もコピーすることなくアクセスできるようにする参照であることを示します。 Rustの強みの1つは、リンクが使いやすいことです(メモリを損傷することはありません)。 現時点では、変数などのリンクがデフォルトで不変であることを知るだけで十分です。 したがって、 &mut guess
&guess
(不変リンクを作成)を記述し、 &mut guess
&guess
(不変リンクを作成)を記述します。
.expect("Failed to read line");
.foo()
構文を使用してメソッドを呼び出すときは、コード行が長くなりすぎないように、新しい行にジャンプすることをお勧めします。 これにより、他のプログラマーがコードを読みやすくなります。
io::stdin().read_line(&mut guess).expect("Failed to read line");
少し難しく読みます。
エラー完了処理( Result
使用)
read_line
読み取るだけでなく、値も返します。ここでは、タイプio::Result
値です。 Rustには、異なるライブラリモジュールにResult
と呼ばれるいくつかのタイプがあります。
- 一般的な
Result
- 特定の例:
io::Result
Result
型は列挙です - 代数的データ型の実装です。 C / C ++では、アナログにunionというタグが付けられます。Result
値は、オプションOk
およびErr
で表すことができます。Ok
は、操作が成功したことを示し、戻り値が含まれます。Err
操作がエラーで完了したことを示し、内部のエラーに関する情報が含まれています。Result
などのResult
固有のメソッドは、Result
型の値に適用されます。Result
型のオブジェクトの値がErr
場合、expect
は渡されたエラーメッセージを表示し、プログラムをクラッシュさせます。 値がOk
場合、expect
はOk
内の値を返します。read_line
ているread_line
関数は(成功した場合)Ok
、ユーザーが入力したバイト数を返します。expect
呼び出さない場合、プログラムはコンパイル時に警告を生成します。
$ cargo build Compiling guessing_game v0.1.0 (file:///projects/guessing_game) warning: unused `std::result::Result` which must be used --> src/main.rs:10:5 | 10 | io::stdin().read_line(&mut guess); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: #[warn(unused_must_use)] on by default
コンパイラは、返されたResult
値を使用しなかったことを通知し、プログラムがエラーの可能性を処理しなかったことを示します。 警告を抑制するには、エラー処理コードを記述する必要がありますが、プログラムがエラーで終了する方法を確認するため、 expect
を使用expect
ます。
printlnを使用した値の印刷!
println!("You guessed: {}", guess); // ,
{}
は「プレースホルダー」であり、受信した行にこの可変プレースホルダーに対応する値があることを示します。 複数の値を印刷するには、複数のプレースホルダーを使用します。最初のプレースホルダー( {}
)は最初の出力値に一致し、2番目から2番目に出力されます。 たとえば、次のように:
let x = 5; let y = 10; println!("x = {} and y = {}", x, y); // : // x = 5 and y = 10
最初の部分の検証
$ 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にはstd
(標準ライブラリ)の乱数を扱うためのモジュールがないため、サードパーティのライブラリ(Rustに関してはcrate) rand
ます。
追加機能にはラックを使用しています。
クレートは、Rustコードの単なるパッケージです。 実行可能バイナリファイル形式の通常プログラムである実行可能クレートを作成しています。 rand
-Cの.oおよび.soファイルに似たライブラリクレート -他のクレートに接続できる関数が含まれています。 貨物は、サードパーティ製のラックの設置に非常に便利です。 rand
クレートの使用を開始するには、 Cargo.tomlに適切な変更を加えて、 rand
を依存関係として含める必要があります。 [依存関係]セクションを変更します
[dependencies] rand = "0.3.14"
Cargo.tomlファイルでは、セクションヘッダーに続くすべてが、新しいセクションが始まるまで続きます。 [dependencies]セクションは、 貨物レートを指定する場所であり、プロジェクトのコードが依存する場所、および必要なバージョンを指定します。 この場合、プロジェクトをビルドするには、バージョン0.3.14
指定子を持つrand
0.3.14
が必要であることを示し0.3.14
。 Cargoは、異なるバージョンのプログラムに名前を付けるための標準の1つであるセマンティックバージョニングモデルを理解しています。 0.3.14
という数値(実際、これは^0.3.14
短縮形です)は、バージョン0.3.14と互換性のあるオープン( パブリック )APIを備えたバージョンが適していることを意味します。 収集しましょう、ただし新しい依存関係があります:
$ cargo build Updating registry `https://github.com/rust-lang/crates.io-index` Downloading rand v0.3.14 Downloading libc v0.2.14 Compiling libc v0.2.14 Compiling rand v0.3.14 Compiling guessing_game v0.1.0 (file:///projects/guessing_game) Finished dev [unoptimized + debuginfo] target(s) in 2.53 secs
Cargoはリポジトリ( レジストリ ) -Crates.ioから依存関係をダウンロードします。 Crates.ioは、Rust開発者がオープンソースプロジェクトを投稿する場所です。 Cargo.tomlは、インデックスをダウンロードした後、まだダウンロードされていない依存関係があるかどうかを確認します。 ある場合は、それらをダウンロードします。 さらに、 rand
は彼に依存しているため、彼はまだlibc
ダウンロードしています。 これは、推移的な依存関係が自動的に解決されることを意味します。 依存関係をダウンロードした後、rustc(Rustコンパイラー)はそれらをコンパイルし、プリコンパイルされた依存関係を使用してプログラム自体をコンパイルします。 再びcargo build
を実行cargo build
と、メッセージは表示されません。 Cargoは、必要な依存関係が既にダウンロードおよびコンパイルされていることを知っており、 Cargo.tomlの [dependencies]セクションを変更していないことを知っています。 Cargoは、コードを変更していないことも知っているため、コードを再コンパイルすることはありません。 完了する必要のある作業がないため、貨物は終了します。 src / main.rsを開いて変更すると、 cargo build
はプロジェクトのコードを再度コンパイルしますが、依存関係は変更されていないため、コンパイルしません( インクリメンタルコンパイル )。
Cargo.lockは、 再現可能なビルドプログラムのビルドを支援します
Cargoには、更新可能なビルドを取得できるツールがあり、他のバージョンの依存関係を指定するまで、指定した依存関係のバージョンのみを使用します。 重要なバグ修正とコードを壊すリグレッションを含むrand
クレートバージョンv0.3.15
たらどうなりますか? この問題を解決するために、 Cargo.lockファイルが使用されます。このファイルは、初めてcagoビルドが起動されたときに作成され、現在はプロジェクトのルートディレクトリにあります。 プロジェクトを初めてアセンブルするとき、Cargoは、指定された要件( Cargo.toml内 )に一致する依存関係番号を見つけ、それらに関する情報をCargo.lockに書き込みます。 2回目以降にプロジェクトをアセンブルすると、CargoはCargo.lockがすでに存在することを確認し、そこに示されているバージョンを使用し、それらを再度表示せず、依存関係の分析に時間を費やします。 これにより、再現可能なアセンブリを取得できます。 つまり、明示的にアップグレードするまで、プロジェクトはrand
0.3.14
バージョン0.3.14
を使用します。
ラックを最新バージョンに更新する
クレートを更新する場合、Cargoはupdateコマンドを提供します。
- Cargo.lockを無視し、 Cargo.tomlで指定した要件を満たす最新の依存関係を見つけます。
- 成功すると、Cargoはこれらの更新されたバージョン番号をCargo.lockに書き込みます
デフォルトでは、Cargoはバージョン>0.3.0
および<0.4.0
を使用します。rand
の作成者が2つの新しいバージョン、たとえば0.3.15
と0.4.0
0.3.15
と、依存関係を更新するときに次のように表示されます(cargo update
)。
$ cargo update Updating registry `https://github.com/rust-lang/crates.io-index` Updating rand v0.3.14 -> v0.3.15
その後、 Cargo.lockのrand
のバージョンが0.3.15に変更されたことに0.3.15
。 rand
バージョン0.4.0
または他のバージョン0.4.x
を使用する場合は、 Cargo.tomlを次のように更新する必要があります。
[dependencies] rand = "0.4.0"
次回、 cargo build
を実行すると、Cargoは使用可能なクレートのインデックスを更新し、依存関係を再確認します。 Cargoを使用すると、サードパーティのライブラリを簡単に接続でき、 コードの再利用に役立ちます。 かんたん
既存のものをビルディングブロックとして使用して、新しいクレートを作成します。
乱数生成
rand
使用に移りましょう。このため、 src / main.rsを更新します
extern crate rand; use std::io; use rand::Rng; fn main() { println!("Guess the number!"); 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); }
extern crate rand;
を追加しましたextern crate rand;
、サードパーティのライブラリを接続する必要があることをrustcに示します。 rand::
記述することでrand::
から関数を呼び出す機会があるため、 use rand
をuse rand
ことにも似ていuse rand
。 use rand::Rng
も追加しました。 Rng
は、乱数ジェネレーターによって実装されるメソッドを定義する特性です。 メソッドを使用できるように、この特性はスコープ内になければなりません。 また、中央に2行追加しました。 rand::thread_rng
関数rand::thread_rng
、オペレーティングシステムによって事前に初期化( シード )されている、現在のスレッドに対してローカルな乱数ジェネレーターを返します。 次に、ジェネレーターでgen_range
を呼び出します。 このメソッドは、以前にuse rand::Rng
演算子をuse rand::Rng
してスコープに導入したRng
で定義されています。 gen_range
は2つの数値を取り、それらの間にある乱数を返します。 範囲には下限が含まれ、上限は含まれません。そのため、1〜100の数字を取得するには、数字1
と101
指定する必要があります。クレートのすべての機能を理解するには、そのドキュメントを読む必要があります。 Cargoのもう1つの可能性は、 cargo doc --open
呼び出してドキュメントを「収集」できることです。その後、ブラウザでドキュメントを開きます(アセンブリ後)。 他のrand
サブ機能に興味がある場合は、左ペインでrand
アイテムを選択します。 追加した2行目は、秘密の番号を出力します。 今のところ、このままにしておきましょう。プログラムの動作を確認するのに便利です。プログラムの最終バージョンにはありません。 数回実行します。
$ 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を変更します
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); 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); match guess.cmp(&secret_number) { Ordering::Less => println!("Too small!"), Ordering::Greater => println!("Too big!"), Ordering::Equal => println!("You win!"), } }
ここで最初のなじみのない要素は、useステートメントの別の使用法です。これは、 std::cmp::Ordering
をstdから scopeに変換します。 Ordering
は別の列挙であり、 Result
に似ていますが、他のオプションがあります。
-
Less
-
Greater
-
Equal
これらは、2つの数値を比較すると得られる3つの結果です。 また、Ordering
タイプを使用してコードを追加しました。
match guess.cmp(&secret_number) { Ordering::Less => println!("Too small!"), Ordering::Greater => println!("Too big!"), Ordering::Equal => println!("You win!"), }
cmp
メソッドは2つの数値を比較し、比較可能な2つのエンティティに関連して呼び出すことができます。 この要素と比較したいものへのリンクを取得します。この場合、 guess
とsecret_number
ます。 cmp
はOrdering
オプションを返します( use
ステートメントを使用して以前にスコープに持ってきました)。 また、 match
一致を使用して、比較の結果に応じて、次に何をするかを決定します。 マッチmatch
はブランチ( arm
)で構成されます。 ブランチは、一致した式がブランチのパターンと一致する場合に実行する必要があるパターンとコードで構成されます。 Rustは、 match
ブランチ内のパターンを使用して式を順番に一致させ、 match
が見つかった後、 match
したパターンの右側のコードが実行されます。 プログラムとの可能な相互作用の例を見てみましょう。 ユーザーが推測として数値50を提案し、秘密(想定)数値が38であるとしましょう。コードが50と38を比較すると、 cmp
メソッドは50> 38であるためOrdering::Greater
返します。 。 match
は最初のブランチOrdering::Less
のテンプレートを調べますが、 Ordering::Greater
値はOrdering::Less
と比較できないため(この場合は等しくないため)、このブランチのコードを無視し、次のテンプレートとの比較を続行します。 次のブランチのテンプレートであるOrdering::Greater
、 Ordering::Greater
( match
を渡しmatch
) Ordering::Greater
同等です。 Too big!
。 match
, . , :
$ 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 | = note: expected type `&std::string::String` = note: found type `&{integer}` error: aborting due to previous error Could not compile `guessing_game`.
, . Rust — , , , . let guess = String::new()
, Rust , guess
String
, . , secret_number
— . 1 100. :
-
i32
— 32- ( ) -
u32
— 32- ( ) -
i64
— 64- ( )
その他。 Rusti32
,secret_number
( , , ,secret_number
, ). , Rust .String
, , , .main
:
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); 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"); 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!"), } }
:
let guess: u32 = guess.trim().parse() .expect("Please type a number!");
guess
. , ? , Rust ( shadow ), . , . ( shadowing ) ( identifier ), , guess_str
guess
. ( bind
) guess
guess.trim().parse()
. guess
guess
, . trim
String
. u32
, ENTER
, ( read_line
). ENTER
, . , 5 ENTER
, guess
5\n
. \n
— , ENTER
. trim
\n
, 5
. parse
String
, . , Rust , let guess: u32
. ( :
) guess
, Rust , ( annotate ) . Rust , , u32
, 32- . . u32
guess
guess
secret_number
, Rust secret_number
u32
. ( u32
). parse
. , , A%
, . - , , parse
Result
, , read_line
. Result
: expect
. parse
Err
- , , expect
, expect
. parse
, parse
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/guessing_game` Guess the number! The secret number is: 58 Please input your guess. 76 You guessed: 76 Too big!
いいね! , , 76. , - :
-
, . , .
loop
. :
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); println!("The secret number is: {}", secret_number); 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 = 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!"), } } }
, . :
$ cargo run Compiling guessing_game v0.1.0 (file:///projects/guessing_game) Running `target/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 note: Run with `RUST_BACKTRACE=1` for a backtrace. error: Process didn't exit successfully: `target/debug/guess` (exit code: 101)
quit
, , - . : , , .
, break
:
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); println!("The secret number is: {}", secret_number); 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 = 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!"); break; } } } }
break
You win!
, , , . , .
, , . , :
let guess: u32 = match guess.trim().parse() { Ok(num) => num, Err(_) => continue, };
expect
match
. , . parse
, Ok
match
, , Ok
( num
), parse
Ok
. guess
. parse
, Err
, . Err
Ok(num)
match
, Err(_)
. _
, , Err(_)
Err
. match
— continue
, . :
$ cargo run Compiling guessing_game v0.1.0 (file:///projects/guessing_game) Running `target/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!
素晴らしい。 .
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; } } } }
おわりに
Rust:
-
let
— (type inference
)
-
match
— - .
static
++ - ( crates )