1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

rustとscalaとkotilnの勉強 数当てゲーム(rust)

Last updated at Posted at 2018-06-23

続き
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

よかったー

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?