続き
rustから
数当てゲームをつくる
TRPLを写経なので特に問題は起きない
cargo new guessing_game
use std::io;
fn main() {
println!("数をあててごらん");
println!("ほら、予想を入力してね");
let mut guess = String::new();
io::stdin().read_line(&mut guess)
.expect("行の読み込みに失敗しました");
println!("次のように予想しました:{}",guess);
}
rustでは基本的に例外というかエラーは戻り値で返ってくる。
ResultでOkかErr
Errでスコンと落としたいときはunwrapで落とすときに文字列を渡せるのがexpect
rustは高階型がないらしいのでモナドやファンクタを型で表現できないらしけど、Resultにはmapやらmap_errやらand_thenがあってそれっぽく使える。
とりま標準入力から読み込んで3超ならOkでそれ以外はErrを返すとするとこんなの
use std::io;
fn main(){
let mut s = String::new();
io::stdin().read_line(&mut s).map_err(|err| err.to_string())
.and_then(|_| s.trim().parse::<i32>().map_err(|err| err.to_string()))
.and_then(|e| if e > 3 { Ok(e) } else { Err(e.to_string()) } ).unwrap();
}
地味にはまったのが「trimしないとparseでこける」
ラムダ式は|prm| -> retType { xxxxx }
||はrubyっぽい??
結構||ってタイプしにくい。慣れの問題だろうか。
read_lineは成功失敗は戻り値で戻るけど、読み込んだ文字列は引き数で渡したsに入ってくるので1回目のand_thenではクロージャの引数は_で指定。
引数使わないときはこれでいいっぽい。でも文法ちゃんと調べてない。コンパイラの警告が消えたからたぶんこれでいいんだろう。
標準ライブラリにランダムがないのでcrates.ioから落とす。
TRPLだとバージョンが0.3.14なんだけど
https://crates.io
で見たら0.5.2なのでそっちで。
https://crates.io
で探してもいいけどcargo search xxxで探してもいい。
extern crate rand;
use std::io;
use std::cmp::Ordering;
use rand::Rng;
fn main(){
let secret_number = rand::thread_rng().gen_range(1,101);
println!("秘密の数字は次の通り:{}",secret_number);
println!("数をあててごらん");
println!("ほら、予想を入力してね");
loop{
let mut guess = String::new();
io::stdin().read_line(&mut guess)
.expect("行の読み込みに失敗しました");
println!("次のように予想しました:{}",guess);
let guess = match guess.trim().parse::<u32>(){
Ok(n) => n,
Err(_) => continue
};
match guess.cmp(&secret_number){
Ordering::Less => println!("ちいさすぎる"),
Ordering::Greater => println!("おおきすぎる"),
Ordering::Equal =>{
println!("せいかい");
break;
}
}
}
}
とりあえず動いたけど問題が。
dockerのコンテナ内で動かしているんだけど、一度コンテナを抜けるとcargo runする度にrandやらlibcやらをダウンロードしちゃう。
どうもCargo.tomlのdependenciesに書いたクレートを
/usr/local/cargo/registry/cache/xxxx/・・・にキャッシュしてるらしく、コンテナを破棄すると(docker runの時に-rmを指定してるからなんだけど)cacheが消えてrunしなおした時にやりなおし・・・になってるっぽい。
cacheのパスを変える方法ないのかな・・・。
scalaのsbtでも似たようなことは起きて、それは.zshrcに
export SBT_OPTS="$SBT_OPTS -Dsbt.ivy.home=/home/xxx/study/scala/.ivy2"
としてマウントしているホストのディレクトリにキャッシュするようにして逃げてる。
毎回毎回ダウンロードされると辛いのでなんとかしたい。
(追記)
.zshrc で CARGO_HOMEを設定したらいけた。
export CARGO_HOME=/home/xxx/study/rust/.cargo
よかったー