最近やや盛り上がりつつあるRustを使ってみることにしました。
試しに、RustとパッケージマネージャCargoを導入してから、Fizz-Buzzを書いてみました。
RustとCargoの導入
Rustの導入
Rustは古いバージョンだと上手く動かなかったりするのでNightlyバージョンを導入しましょう。
Homebrewだとちょっと古いバージョンになるので、今回は公式ページからMac binaries (.tar.gz) の64-bit版をダウンロードしました。
インストールにはこれを解凍してinstall.sh
を実行するだけです。
$ 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
にパスを通せばよいです。
$ 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
に置きました。
$ cargo version cargo 0.0.1-pre-nightly (3139954 2014-09-03 05:22:14 +0000)
新規プロジェクトの作成
CargoでRustの新規プロジェクトを作成するにはcargo new
します。
$ cargo new --bin --git fizzbuzz
プロジェクト用ディレクトリfizzbuzz
が生成されます。
$ cd fizzbuzz $ ls -a ./ ../ .git/ .gitignore Cargo.toml src/ $ ls src main.rs
--bin
を付けたのでバイナリ向けのテンプレートが生成されており、--git
を付けたので.git
と.gitignore
が生成されています。
ファイルはトラックされていないので、すぐにcommitしてしまってもよいでしょう。
cargo用の設定ファイルCargo.tomlはこんな感じ。今回は何も手を入れずに利用しています。
$ cat Cargo.toml [package] name = "fizzbuzz" version = "0.0.1" authors = ["Safx <safxdev@example.com>"]
ちなみにcargo
を引数なしで実行するとこんな感じになります。
$ 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
で生成されたソースファイルはこんな感じです。
$ cat src/main.rs fn main() { println!("Hello, world!") }
とりあえずコンパイルしてみます。これにはcargo build
するだけです。
$ cargo build Compiling fizzbuzz v0.0.1 (file:///Users/safx/src/fizzbuzz)
これで、target
というディレクトリが生成されて、その中にfizzbuzz
というバイナリが生成されます。
$ ./target/fizzbuzz Hello, world!
テストを書く
テストファーストでFizz-Buzzを書いていきますので、テストとfizzbuzzの空実装を書きます。
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]
がある関数はテストケースとしてテスト時に実行されます。テストを実行してみましょう。
$ 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
このテストを通すようにします。
fn fizzbuzz(n: int) -> String { if n % 3 == 0 { "fizz".to_string() } else { "".to_string() } }
これでテストが通るようになりました。
$ 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がこちら。
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みたいですね。
$ 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 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。