Rust でコマンドライン引数を扱う (1) std::env::args

Rust プログラムに渡されたコマンドライン引数を扱う方法として、std::env::args 関数 を使う方法を説明します。 この関数は標準で呼び出すことができるのでお手軽ですが、リッチなコマンドライン引数を提供したいときは、clap クレートを使う方法 がおすすめです。

std::env::args の基本

std::env::args 関数は、イテレート可能な std::env::Args オブジェクトを返します。 1 番目の要素には実行したファイルの名前(相対パス)が含まれており、2 番目以降にコマンドライン引数が格納されています。

src/main.rs
use std::env;

fn main() {
    // std::env::Args を取得してループ処理
    for arg in env::args() {
        println!("{arg}");  // arg は単純な String 型
    }
}

cargo run でコマンドを実行する場合、プログラムに渡すコマンドライン引数は、次のように -- の後ろに指定します。

実行例
$ cargo -q run -- --aaa 100 200
target/debug/sample
--aaa
100
200

-- というセパレーターを入れないと、--aaa オプションが、cargo 側のオプションとして渡されてしまうので注意してください。

Iterator トレイトの nth メソッド を使って、インデックス指定で参照することもできます。 ユーザーがコマンドライン引数を指定しなかった場合は、Option::None が返されることに注意してください。

let first_arg: String = std::env::args().nth(1).unwrap();
let second_arg: String = std::env::args().nth(2).unwrap();

ベクター型で処理する (collect)

std::env::args 関数の戻り値 Args は、次のように Vec<String> 型に変換してしまうと扱いやすいです。

use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();

    // すべての内容をダンプ
    println!("{:?}", args);

    // 各パートを取り出す
    println!("The number of arguments is {}", args.len());
    println!("My path is {}", args[0]);
    println!("The remaining arguments are {:?}", &args[1..]);

    // 必須の引数を表現したい場合
    if args.len() < 2 {
        eprintln!("The dir_name argument is required");
        std::process::exit(1);
    }
    let dir_name = args.get(1).unwrap();
    println!("dir_name = {}", dir_name);
}

次のステップ