何かを書き留める何かスマートフォン用の表示で見る何かを書き留める何か数学や読んだ本について書く何かです。最近は社会人として生き残りの術を学ぶ日々です。edition』の続き。2章は推測ゲームの実装によるチュートリアル。ProjectまずはCargoでプロジェクトを新規作成する。1章でインストールだけしていきなり2章を読み始めても何とかなる安心設計。runで必要に応じてビルドしてくれるので段階を踏みつつコマンドを叩けば継続的な開発ができる。Guessr最初はユーザーからの入力、入力値が期待通りであるかの確認を行う。部分を改行させないようにする。print!にすれば動きそうだ。222おっと、期待した動作をしていない。改行\nで出力をバッファからフラッシュしているようである。そこで、無理やり(?)吐き出させる。}今度はどうなるかな。10欲しかった形になった。その中身を取り出している処理を行っている。詳しくはエラーハンドリングで行うらしい。ここでは見栄えの問題なので深追いはしない。このプログラムをひとつづつ調べる。標準ライブラリからioライブラリを読み込む。呼ばれるライブラリを読み込む。1章を流し読みした人でもfnやprintln!の説明が書かれているので安心。デフォルトで、変数はイミュータブルとなる。ミュータブルな変数にする場合は変数名の前にmutをつける。ミュータブルな変数guessをString::new()の返り値に束縛する。UTF-8エンコードされた文字列。String::newの::はStringの関連函数(正確な日本語訳は不明)を呼び出す。標準入力から値を読み込んでguessに渡す。guessはミュータブルである。変数定義やread_lineの引数からmutを外すとコンパイルエラーとなる。変数の参照を意味する(C言語と一緒ですね)。Rustの売りの一つに参照を安全に扱うことが出来る点がある(という宣伝)。4章で詳しく取り扱う。ような例が学習初期に出てきたときに「この&はおまじないで...」とごまかす教材があるが、このチュートリアルはそれなりに分かっている人向けなので逃げずに参照と明言する。返り値はio::Result型を返す。RustにはResult型が標準ライブラリにたくさんある。Result型は列挙型である。ResultはOkとErrの2つのバリアントを持つ、Okには正しく生成された値が、Errにはなぜ、どのように失敗したのかの情報が含まれる。Resultの目的はエラーハンドリング情報をエンコードする(意味がうまく取れないが言わんとしていることはわかる)ためにある、io::Result型のインスタンスはexpectメソッドを持つ。io::ResultインスタンスがErrの値を持っているならば、expcetメソッドはプログラムをクラッシュさせ(!)expectの引数に渡したメッセージを出力する。io::ResultがOkの値を持っているならばexpectはOkが持つ値を返す。今回はユーザーが入力した値を返す。expectを呼ばない場合はコンパイル時に警告が出る。defaultResultの値を使用していないとエラー処理をしていないということで警告を出す。先ほどの閑話でプロンプトっぽいものを実現するためにバッファをフラッシュしている。その際にio::stdout().flush().unwrap();としているが、これもio::stdout().flush();とすると警告が出る。unwrap()とすることでResult型のインスタンスを処理(エラーの握りつぶし!)している。{}はプレースホルダ。他の言語にもよくある。Part推測ゲーム実装の第一弾のテスト(標準入力)のテストを行う。1確かに所望の動作を行っている。Number推測ゲームなのでゲーム側が推測してほしい乱数を生成する必要がある。プレイのたびに推測する値は変化してほしい。Rustには標準ライブラリに乱数ライブラリは存在しないが、Rustチームがrandクレートを用意している。クレートはRustのパッケージ。Functionality今まで作ってきたのはバイナリクレートであり、実行可能である。randクレートはライブラリクレートで、別のプログラムから使われることを意図したものである。外部ライブラリを使うときこそCargoが輝く(ビルドツールだからね!)。randクレートを使うにはCargo.tomlに依存関係としてrandを追加する。"0.3.14"バージョン記述はセマンティックバージョニングに従う。secs外部ライブラリはCrates.ioから取得する。最近の言語(Perl以降?)はこの手のレポジトリが必ずある気がする。TeXだってCTANがあるのだし。ドキュメントにある出力結果とは異なり、環境がWindowsであったのでWindows向けと思われるライブラリクレートwinapiも一緒にやってきた。BuildsCargo.lockファイルでバージョンの固定ができる。cargo.tomlではセマンティックバージョニングなので以上やら以下やらが入るが、一度実行すれば明示的にアップグレードするまではCargo.lockファイルの記述に従う。このあたり、Pythonのrequirements.txtとの違いにまだ体が慣れていない。requirements.txtにあたる操作であろう。updateコマンドがある。私の環境では何も起きなかった...。Numberやっと乱数を使う。}推測する数字は不変であるべきなのでmutはつけていない。rand;のようにする。これでrandクレートがrand::で使える。thread_rng()は乱数ジェネレータの1つ。gen_rangeは引数に渡した範囲の乱数を生成するメソッド(関連函数か?)。追加し忘れると、以下のような憂き目にあう。`guessing_game`.とはいえ、きちんとエラーメッセージに案内がでるので(ドキュメントを読めという話であるが)安心である。--openでドキュメントが読めるのでこれは読めということである。コンパイルできるように修正して実行すると、確かに乱数が生成されている。Number乱数と入力値を比較する。}}std::cmp::Orderingは標準ライブラリにあり、Result型と同様に列挙型であるが、Less、Greater、Equalを持つ。guess.cmpのcmpメソッドでsecret_numberと比較を行う。matchはパターンマッチングか。昔、Haskellでもパターンマッチングを見て強力な云々という解説を読んだ覚えがあるが、Rustでもやはり重要なのだろうか。`guessing_game`.おっと、文字列型と数値型(ここでは符号つき32bit整数)を比較しているようである(ドキュメント通りの誘導に乗っかっている)。PHPやPerlでは「いい感じに」解釈して比較してくれた気がするが、どちらが幸せだろうか。僕は比較できないほうが幸せだと思う。適切な比較をするために、入力値を実数(?)に変換して比較を行う。}}変数guessを再利用できる。このような操作をシャドーイングと呼び、詳しくは3章で取り扱う。型に厳密にありながらこの機能は便利である(が、変なミスにもつながりそう)。標準入力の値には改行が含まれるので、trim()で改行を取り除く。trim()はPerlっぽい印象をうける。parse()で文字列を何かしらの数値に変換する。u32のように注釈をつけてRustに教える。ここでは符号なし32bit整数に変換している。文字を数値として変換できない場合も多々あるので、きちんとResult型の処理を行う。変換できたので、実行する。small!うまくいった。標準入力に負数を入れると破綻する。Looping現状だと1回しかできないので、繰り返し実行させる。}}ぱっと見無限ループなので怖いが実行する。101)やはり無限ループだった。Guess正解を入力したら停止させたいのは当然そう思うことである。正解したらループを抜けるようにする。Inputまちがった入力してもゲームを続けることができるようにしよう。}}今までexpectでクラッシュさせていた部分をmatchでエラーハンドリングを行っている。};見た目通りの動きをしている。最後に、デバッグ用のprint!マクロを削除して推測ゲームの実装が完了する。match、メソッド、関連函数、外部クレート)を実践的な方法で学んだ(完全に理解できたとは言っていない)。3章ではよくある概念の話、4章ではRust特有のオーナ0シップの話、5章は構造体とメソッド、6章では列挙型について。3章は他の言語の経験があればおそらく読めると思うが、4章のオーナーシップが山場になりそうである。»プロフィールid:XaroCydeykn数学や計算機、読んだ本について書くブログのような何かです。(1)最近人気の記事はてなブログをはじめよう!XaroCydeyknさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。