Rust雑入門2
お品書き
- Cargoの使い方
- Docopt.rsについて
Cargo
Cargoとは
- Rustのパッケージマネージャー
- RubyでいうBundler(作者が同じ)
- Cargo.tomlに依存パッケージなどを書けば
- Cargo run など必要な時に取得・コンパイルしてくれる
- Rustのオフィシャルツール
パッケージマネージャーの決めてる欠けるGoに比べるとすごく楽- Rustをインストールした時点で一緒にインストールされている
Cargo
基本コマンド
- cargo new でライブラリの開発プロジェクト開始
- cargo new --bin では実行用のバイナリを書く
- cargo run で実行
- cargo test でテストを実行
- cargo build でビルド(開発デバッグ用)
- cargo build --release で最適化してビルド
- cargo help を見ればOK
- じっくり学びたい人は Cargo Guideを参照
Cargo
Hello World
with Cargo
CargoでHello World!
cargo new --bin hello
cd hello
cargo run
ビルドされ、"Hello, world!" と出力される
CargoでHello World!
├── .git
├── .gitignore
├── Cargo.toml
└── src
└── main.rs
hello ディレクトリの構成
CargoでHello World!
├── .git
├── .gitignore
├── Cargo.toml
└── src
└── main.rs
hello ディレクトリの構成
デフォルトでGitがバージョン管理に使われる
CargoでHello World!
├── .git
├── .gitignore
├── Cargo.toml
└── src
└── main.rs
hello ディレクトリの構成
パッケージの情報と依存パッケージなどを書き込む
インストールされたパッケージはCargo.lockで
バージョンが固定される
CargoでHello World!
├── .git
├── .gitignore
├── Cargo.toml
└── src
└── main.rs
hello ディレクトリの構成
cargo runで実行されるのがsrc/main.rs
このファイルを開くとhello worldを出力するプログラムが書いてある。(仕様)
今回はこれを編集していく
Docopt
docopt
- コマンドのヘルプをパーズして、引数やオプションを利用できる便利なライブラリ
- 各言語にライブラリが存在する
- ただしGo版はあまりイケてない(type assertion)
- Cargoでも使われている
Docoptとは
docopt
- 今回もなんちゃってcat
- 標準入力無視
- -nだけ対応
プロジェクトを開始
cargo new --bin cat
docopt
- Cargo.tomlに[dependencies]を追加
- docopt = "*" で最新版をインストール
- rustc-serializeも必要なので入れる
Docoptのインストール
# Cargo.toml
[dependencies]
docopt = "*"
rustc-serialize = "*"
docopt
Docoptでパーズした結果のargsをprintln!で表示する例(開発用)。各行を解説していく!
extern crate rustc_serialize;
extern crate docopt;
use docopt::Docopt;
const USAGE: &'static str = "
Usage:
cat [options] [<file>...]
Options:
-h, --help Display this message
-n Number the output lines, starting at 1.
";
#[derive(Debug, RustcDecodable)]
struct Args {
arg_file: Option<Vec<String>>,
flag_n: bool,
}
fn main() {
let args: Args = Docopt::new(USAGE)
.and_then(|d| d.decode())
.unwrap_or_else(|e| e.exit());
println!("{:?}", args);
}
docopt
extern crateはRubyでいうrequire
useについは前回のスライドを参照
extern crate rustc_serialize;
extern crate docopt;
use docopt::Docopt;
docopt
const &'static str は定数
const USAGE: &'static str = "
Usage:
cat [options] [<file>...]
Options:
-h, --help Display this message
-n Number the output lines, starting at 1.
";
docopt
catの引数やオプションの書式
[]は省略可能
-はフラグ、値がない場合はbool
<>は引数 ... は可変
詳しくは以下を参照
const USAGE: &'static str = "
Usage: cat [options] [<file>...]
Options:
-h, --help Display this message
-n Number the output lines, starting at 1.
";
docopt
deriveは指定したTraitを自動で実装させるアトリビュート
Debugはprintln!("{:?}")で、表示できるようにするTrait、{}で表示させるにはDisplay
RustcDecodableはDocOptが使用している
(今回に限っての話)
#[derive(Debug, RustcDecodable)]
struct Args {
arg_file: Option<Vec<String>>,
flag_n: bool,
}
docopt
Argsというstructを定義している
#[derive(Debug, RustcDecodable)]
struct Args {
arg_file: Option<Vec<String>>,
flag_n: bool,
}
docopt
メンバ変数、プロパティの定義といったところ
メソッドの実装はimplを使って別に定義する
メソッド定義については別の機会に...
[<file>...]は省略可能なのでOption
<file>...は文字列の配列になるのでVec<String>
今回はあえて省略可能にしている
#[derive(Debug, RustcDecodable)]
struct Args {
arg_file: Option<Vec<String>>,
flag_n: bool,
}
docopt
-nは値なしなのでbool
-nが指定されているとtrue
省略の場合はfalseが入る
実際に入ってくる値をcargo runで確かめよう
#[derive(Debug, RustcDecodable)]
struct Args {
arg_file: Option<Vec<String>>,
flag_n: bool,
}
docopt
cargo runで、実行対象に引数を渡す時は--をつけて、その後ろに渡す
--より前はcargo run自体の引数(--verboseなど)
cargo run -- -n a b c
docopt
引数がちゃんとパーズされて取れていることがわかる
cargo run -- -n a b c
# Running `target/debug/cat -n a b c`
# Args { arg_file: Some(["a", "b", "c"]), flag_n: true }
続く...
Rust雑入門2
By dopin
Rust雑入門2
- 1,161