錆のチュートリアルでは、コマンドラインからパラメータを取る方法を説明していません。fn main()
すべての例で、空のパラメーターリストでのみ表示されます。
からコマンドラインパラメータにアクセスする正しい方法は何main
ですか?
錆のチュートリアルでは、コマンドラインからパラメータを取る方法を説明していません。fn main()
すべての例で、空のパラメーターリストでのみ表示されます。
からコマンドラインパラメータにアクセスする正しい方法は何main
ですか?
回答:
std::env::args
またはstd::env::args_os
関数を使用して、コマンドライン引数にアクセスできます。どちらの関数も引数の反復子を返します。前者はString
s(処理が簡単)を反復しますが、引数の1つが有効なUnicodeでない場合はパニックになります。後者はOsString
sを繰り返し、パニックになることはありません。
反復子の最初の要素はプログラム自体の名前であることに注意してください(これはすべての主要なOSでの規則です)、最初の引数は実際には2番目の反復要素です。
の結果を処理する簡単な方法args
は、それをaに変換することVec
です。
use std::env;
fn main() {
let args: Vec<_> = env::args().collect();
if args.len() > 1 {
println!("The first argument is {}", args[1]);
}
}
標準のイテレータツールボックス全体を使用して、これらの引数を操作できます。たとえば、最初の引数のみを取得するには:
use std::env;
fn main() {
if let Some(arg1) = env::args().nth(1) {
println!("The first argument is {}", arg1);
}
}
コマンドライン引数を解析するためのライブラリがcrates.ioにあります。
DocoptはRustでも使用できます。Rustは、使用法の文字列からパーサーを生成します。Rustのボーナスとして、マクロを使用して構造体を自動的に生成し、型ベースのデコードを実行できます。
docopt!(Args, "
Usage: cp [-a] SOURCE DEST
cp [-a] SOURCE... DIR
Options:
-a, --archive Copy everything.
")
そして、あなたは引数を得ることができます:
let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit());
READMEとドキュメントには、完全に機能する例がたくさんあります。
免責事項:私はこのライブラリの作成者の1人です。
Rustにはgetopt
、getoptsクレートに -style CLI引数解析機能があります。
私にとって、getoptsは常に低レベルに感じられ、docopt.rsはあまりにも魔法のようでした。私はそれらが必要な場合にすべての機能を提供する明示的で簡単なものを求めています。
ここでclap-rsが役に立ちます。
Pythonのargparseに少し似ています。これがどのように見えるかの例です:
let matches = App::new("myapp")
.version("1.0")
.author("Kevin K. <kbknapp@gmail.com>")
.about("Does awesome things")
.arg(Arg::with_name("CONFIG")
.short("c")
.long("config")
.help("Sets a custom config file")
.takes_value(true))
.arg(Arg::with_name("INPUT")
.help("Sets the input file to use")
.required(true)
.index(1))
.arg(Arg::with_name("debug")
.short("d")
.multiple(true)
.help("Sets the level of debugging information"))
.get_matches();
次のようにパラメーターにアクセスできます。
println!("Using input file: {}", matches.value_of("INPUT").unwrap());
// Gets a value for config if supplied by user, or defaults to "default.conf"
let config = matches.value_of("CONFIG").unwrap_or("default.conf");
println!("Value for config: {}", config);
(公式ドキュメントからコピー)
バージョン0.8 / 0.9以降、関数args()への正しいパスは次のようになります::std::os::args
。
fn main() {
let args: ~[~str] = ::std::os::args();
println(args[0]);
}
現在、Rustは標準のIOでもまだかなり変動しているようです。そのため、これはすぐに古くなる可能性があります。
さびは再び変わった。os::args()
の代わりに非推奨ですstd::args()
。しかしstd::args()
、配列ではなく、イテレータを返します。コマンドライン引数を反復処理できますが、添え字を使用してそれらにアクセスすることはできません。
http://doc.rust-lang.org/std/env/fn.args.html
コマンドライン引数を文字列のベクトルとして必要な場合、これは今動作します:
use std::env;
...
let args: Vec<String> = env::args().map(|s| s.into_string().unwrap()).collect();
Rust-変化の痛みを受け入れることを学びます。
env::args().collect()
。
structoptもチェックしてください:
extern crate structopt;
#[macro_use]
extern crate structopt_derive;
use structopt::StructOpt;
#[derive(StructOpt, Debug)]
#[structopt(name = "example", about = "An example of StructOpt usage.")]
struct Opt {
/// A flag, true if used in the command line.
#[structopt(short = "d", long = "debug", help = "Activate debug mode")]
debug: bool,
/// An argument of type float, with a default value.
#[structopt(short = "s", long = "speed", help = "Set speed", default_value = "42")]
speed: f64,
/// Needed parameter, the first on the command line.
#[structopt(help = "Input file")]
input: String,
/// An optional parameter, will be `None` if not present on the
/// command line.
#[structopt(help = "Output file, stdout if not present")]
output: Option<String>,
}
fn main() {
let opt = Opt::from_args();
println!("{:?}", opt);
}
新しいRustバージョン(Rust> 0.10 / 11)では、配列構文は機能しません。getメソッドを使用する必要があります。
[編集]配列構文は毎晩(再び)機能します。したがって、ゲッターインデックスか配列インデックスかを選択できます。
use std::os;
fn main() {
let args = os::args();
println!("{}", args.get(1));
}
// Compile
rustc args.rs && ./args hello-world // returns hello-world
Vec
sのインデックス構文をサポートしています。1ヶ月くらいはあると思います。この例を参照してください。
Rustは2013年5月のCalvinの回答以来進化してきました。今では、コマンドライン引数をas_slice()
次のように解析します:
use std::os;
fn seen_arg(x: uint)
{
println!("you passed me {}", x);
}
fn main() {
let args = os::args();
let args = args.as_slice();
let nitems = {
if args.len() == 2 {
from_str::<uint>(args[1].as_slice()).unwrap()
} else {
10000
}
};
seen_arg(nitems);
}
as_slice()
もう存在しないので、&args
代わりに使用する必要があります。
錆ブック「いいえSTDLIB」の章のコマンドラインパラメータ(別の方法)にアクセスする方法を説明します。
// Entry point for this program
#[start]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
0
}
さて、この例には#![no_std]
、通常、stdライブラリがバイナリの真のエントリポイントを持ち、と呼ばれるグローバル関数を呼び出すことを意味すると思いますmain()
。別のオプションは、でmain
シムを無効にすること#![no_main]
です。プログラムの開始方法を完全に制御していることをコンパイラに言っているのは間違いではありません。
#![no_std]
#![no_main]
#[no_mangle] // ensure that this symbol is called `main` in the output
pub extern fn main(argc: isize, argv: *const *const u8) -> isize {
0
}
コマンドライン引数を読み取るだけの場合は、これが「良い」方法だとは思いません。std::os
他の回答に記載されたモジュールは、物事のより良い方法のようです。完成のためにこの回答を掲載します。
println(args[0])