最近やや盛り上がりつつあるRustを使ってみることにしました。
試しに、RustとパッケージマネージャCargoを導入してから、Fizz-Buzzを書いてみました。
RustとCargoの導入
Rustの導入
Rustは古いバージョンだと上手く動かなかったりするのでNightlyバージョンを導入しましょう。
Homebrewだとちょっと古いバージョンになるので、今回は公式ページからMac binaries (.tar.gz) の64-bit版をダウンロードしました。
インストールにはこれを解凍してinstall.sh
を実行するだけです。
1 2 3 | $ tar zxvf ~ /Downloads/rust-nightly-x86_64-apple-darwin . tar .gz $ cd rust-nightly-x86_64-apple-darwin $ . /install .sh |
これで、/usr/localあたりにrustc
がインストールされます。あとは、/usr/local/bin
にパスを通せばよいです。
1 2 | $ rustc --version rustc 0.12.0-pre-nightly (2e3858179 2014-09-03 00:51:00 +0000) |
Cargo
パッケージマネージャのCargoはGitHubページのリンクからx86_64-apple-darwin
をダウンロードして、その中のファイルcargo
を/usr/local/bin
に置きました。
1 2 | $ cargo version cargo 0.0.1-pre-nightly (3139954 2014-09-03 05:22:14 +0000) |
新規プロジェクトの作成
CargoでRustの新規プロジェクトを作成するにはcargo new
します。
1 | $ cargo new --bin --git fizzbuzz |
プロジェクト用ディレクトリfizzbuzz
が生成されます。
1 2 3 4 5 | $ cd fizzbuzz $ ls -a ./ ../ .git/ .gitignore Cargo.toml src/ $ ls src main.rs |
--bin
を付けたのでバイナリ向けのテンプレートが生成されており、--git
を付けたので.git
と.gitignore
が生成されています。
ファイルはトラックされていないので、すぐにcommitしてしまってもよいでしょう。
cargo用の設定ファイルCargo.tomlはこんな感じ。今回は何も手を入れずに利用しています。
1 2 3 4 5 6 | $ cat Cargo.toml [package] name = "fizzbuzz" version = "0.0.1" authors = [ "Safx <safxdev@example.com>" ] |
ちなみにcargo
を引数なしで実行するとこんな感じになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | $ cargo Rust's package manager Usage: cargo < command > [<args>...] cargo [options] Options: -h, --help Display this message -V, --version Print version info and exit --list List installed commands - v , --verbose Use verbose output Some common cargo commands are: build Compile the current project clean Remove the target directory doc Build this project 's and its dependencies' documentation new Create a new cargo project run Build and execute src /main .rs test Run the tests bench Run the benchmarks update Update dependencies listed in Cargo.lock See 'cargo help <command>' for more information on a specific command . |
試しにコンパイル
cargo new
で生成されたソースファイルはこんな感じです。
1 2 3 4 | $ cat src /main .rs fn main() { println!( "Hello, world!" ) } |
とりあえずコンパイルしてみます。これにはcargo build
するだけです。
1 2 | $ cargo build Compiling fizzbuzz v0.0.1 ( file : ///Users/safx/src/fizzbuzz ) |
これで、target
というディレクトリが生成されて、その中にfizzbuzz
というバイナリが生成されます。
1 2 | $ . /target/fizzbuzz Hello, world! |
テストを書く
テストファーストでFizz-Buzzを書いていきますので、テストとfizzbuzzの空実装を書きます。
1 2 3 4 5 6 7 8 9 10 | fn fizzbuzz(n: int) -> String { "".to_string() } #[test] fn test_fizz() { assert_eq!(fizzbuzz(3), "fizz".to_string()) assert_eq!(fizzbuzz(6), "fizz".to_string()) assert_eq!(fizzbuzz(9), "fizz".to_string()) } |
Rustでは#[test]
がある関数はテストケースとしてテスト時に実行されます。テストを実行してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | $ cargo test Compiling fizzbuzz v0.0.1 ( file : ///Users/safx/src/fizzbuzz ) /Users/safx/src/fizzbuzz/src/main .rs:1:1: 3:2 warning: code is never used: `main`, #[warn(dead_code)] on by default /Users/safx/src/fizzbuzz/src/main .rs:1 fn main() { /Users/safx/src/fizzbuzz/src/main .rs:2 println!( "Hello, world!" ) /Users/safx/src/fizzbuzz/src/main .rs:3 } /Users/safx/src/fizzbuzz/src/main .rs:5:14: 5:15 warning: unused variable: `n`, #[warn(unused_variable)] on by default /Users/safx/src/fizzbuzz/src/main .rs:5 fn fizzbuzz(n: int) -> String { ^ Running target /fizzbuzz-c2448ebfc140711f running 1 test test test_fizz ... FAILED failures: ---- test_fizz stdout ---- task 'test_fizz' failed at 'assertion failed: `(left == right) && (right == left)` (left: ``, right: `fizz`)' , /Users/safx/src/fizzbuzz/src/main .rs:11 failures: test_fizz test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured |
このテストを通すようにします。
1 2 3 4 5 6 7 | fn fizzbuzz(n: int) -> String { if n % 3 == 0 { "fizz".to_string() } else { "".to_string() } } |
これでテストが通るようになりました。
1 2 3 4 5 6 7 8 9 10 11 12 | $ cargo test Compiling fizzbuzz v0.0.1 ( file : ///Users/safx/src/fizzbuzz ) /Users/safx/src/fizzbuzz/src/main .rs:1:1: 3:2 warning: code is never used: `main`, #[warn(dead_code)] on by default /Users/safx/src/fizzbuzz/src/main .rs:1 fn main() { /Users/safx/src/fizzbuzz/src/main .rs:2 println!( "Hello, world!" ) /Users/safx/src/fizzbuzz/src/main .rs:3 } Running target /fizzbuzz-c2448ebfc140711f running 1 test test test_fizz ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured |
実装
そんなこんなで完成したFizz-Buzzがこちら。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | fn main() { for i in range(1, 31) { println!("{}", fizzbuzz(i)) } } fn fizzbuzz(n: int) -> String { if n % 15 == 0 { "fizzbuzz".to_string() } else if n % 3 == 0 { "fizz".to_string() } else if n % 5 == 0 { "buzz".to_string() } else { n.to_string() } } #[test] fn test_num() { assert_eq!(fizzbuzz(1), "1".to_string()) assert_eq!(fizzbuzz(2), "2".to_string()) assert_eq!(fizzbuzz(4), "4".to_string()) assert_eq!(fizzbuzz(29), "29".to_string()) } #[test] fn test_fizz() { assert_eq!(fizzbuzz(3), "fizz".to_string()) assert_eq!(fizzbuzz(6), "fizz".to_string()) assert_eq!(fizzbuzz(9), "fizz".to_string()) } #[test] fn test_buzz() { assert_eq!(fizzbuzz(5), "buzz".to_string()) assert_eq!(fizzbuzz(10), "buzz".to_string()) assert_eq!(fizzbuzz(20), "buzz".to_string()) } #[test] fn test_fizzbuzz() { assert_eq!(fizzbuzz(15), "fizzbuzz".to_string()) assert_eq!(fizzbuzz(30), "fizzbuzz".to_string()) } |
ちなみに、cargo run
で実行できます。コンパイルはそれなりに早いので割と気軽に実行できます。Goみたいですね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | $ cargo run Compiling fizzbuzz v0.0.1 ( file : ///Users/safx/src/fizzbuzz ) Running `target /fizzbuzz ` 1 2 fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz 16 17 fizz 19 buzz fizz 22 23 fizz buzz 26 fizz 28 29 fizzbuzz |
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。