やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

Rustでコマンドライン引数を受け取る

 コマンドラインツールを作るために。

成果物

参考

コード

main.rs

fn main() {
    let args: Vec<String> = std::env::args().collect();
    println!("args: {:?}", args);
}

実行

$ rustc main.rs
$ ./main A B C
args: ["./main", "A", "B", "C"]

クレートの場合

$ cargo new minigrep
$ cd minigrep
(コード作成)
$ cargo run A B C
...
args: ["target/debug/minigrep", "A", "B", "C"]

2レベル以上ネストされているときのuse

 std::env::args().collect();args()関数を呼び出すもの。その前にモジュールが2階層ある。std, envである。このとき、関数を直接useするのでなく、その親をuseするのが因習的らしい。

use std::env;
fn main() {
    let args: Vec<String> = env::args().collect();
    println!("{:?}", args);
}

文字コードによる問題

 Unicode以外の文字コードを受け取る必要があるときはstd::env::args_osを使うらしい。

 私の環境(OS)は文字コードUnicodeだから問題ない。でもWindowsSJISだからargs_osを使い面倒な文字コード処理が必要なのかも?

 ドキュメントの書き方がいやらしい。

引数のどれかが不正なユニコードを含んでいたら、std::env::argsはパニックすることに注意してください。 プログラムが不正なユニコードを含む引数を受け付ける必要があるなら、代わりにstd::env::args_osを使用してください。

 ここでいう「不正なユニコード」とはユニコード以外の文字コードを指していると思われる。つまり日本語WindowsではSJISが使われているから、そのときはargs_os()を使えという意味だと思う。確認は取れていない。

collect()と型注釈

let args: Vec<String> = std::env::args().collect();
  1. args()イテレータを生成する
  2. collect()でベクタに変換する
  3. Vec<String>として型を明示せねばならない

 もし型注釈せず以下コードにすれば、以下エラーになる。

let args = std::env::args().collect();
$ rustc main.rs
error[E0282]: type annotations needed
 --> main.rs:7:9
  |
7 |     let args = std::env::args().collect();
  |         ^^^^
  |         |
  |         cannot infer type
  |         consider giving `args` a type

error: aborting due to previous error

For more information about this error, try `rustc --explain E0282`.

 正直、指示せずとも自動的にやってほしい。

 ドキュメントでは「型を注釈しなければならない頻度は非常に少ない」などと言っているが、この手の処理(collect())はよく使うであろうことから、とても頻度が少ないとは思えない。ライフタイム注釈といい、Rustはコンパイラに指示せねばならないことがしばしば現れるて面倒。

引数値を変数に保存する

コード

fn main() {
    let args: Vec<String> = std::env::args().collect();
    let query = &args[1];
    let filename = &args[2];
    println!("query: {}", query);
    println!("filename: {}", filename);
}

実行

$ cargo run A B C
...
query: A
filename: B

対象環境

$ uname -a
Linux raspberrypi 4.19.42-v7+ #1219 SMP Tue May 14 21:20:58 BST 2019 armv7l GNU/Linux

前回まで