The Rust tutorial tidak menjelaskan bagaimana untuk mengambil parameter dari baris perintah. fn main()
hanya ditampilkan dengan daftar parameter kosong di semua contoh.
Dari mana cara yang benar mengakses parameter baris perintah main
?
The Rust tutorial tidak menjelaskan bagaimana untuk mengambil parameter dari baris perintah. fn main()
hanya ditampilkan dengan daftar parameter kosong di semua contoh.
Dari mana cara yang benar mengakses parameter baris perintah main
?
Jawaban:
Anda dapat mengakses argumen baris perintah dengan menggunakan fungsi std::env::args
atau std::env::args_os
. Kedua fungsi mengembalikan iterator atas argumen. Mantan iterates over String
s (yang mudah untuk bekerja dengan) tetapi panik jika salah satu argumen tidak valid unicode. Yang terakhir ini berulang-ulang OsString
dan tidak pernah panik.
Perhatikan bahwa elemen pertama dari iterator adalah nama dari program itu sendiri (ini adalah konvensi di semua OS utama), jadi argumen pertama sebenarnya adalah elemen iterated kedua.
Cara mudah untuk menangani hasilnya args
adalah dengan mengubahnya menjadi Vec
:
use std::env;
fn main() {
let args: Vec<_> = env::args().collect();
if args.len() > 1 {
println!("The first argument is {}", args[1]);
}
}
Anda dapat menggunakan seluruh kotak alat iterator standar untuk bekerja dengan argumen ini. Misalnya, untuk mengambil hanya argumen pertama:
use std::env;
fn main() {
if let Some(arg1) = env::args().nth(1) {
println!("The first argument is {}", arg1);
}
}
Anda dapat menemukan pustaka di crates.io untuk parsing argumen baris perintah:
Docopt juga tersedia untuk Rust, yang menghasilkan parser untuk Anda dari string penggunaan. Sebagai bonus di Rust, makro dapat digunakan untuk secara otomatis menghasilkan struct dan melakukan decoding berdasarkan tipe:
docopt!(Args, "
Usage: cp [-a] SOURCE DEST
cp [-a] SOURCE... DIR
Options:
-a, --archive Copy everything.
")
Dan Anda bisa mendapatkan argumen dengan:
let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit());
README dan dokumentasi memiliki banyak contoh yang berfungsi penuh.
Penafian: Saya adalah salah satu penulis perpustakaan ini.
Rust memiliki getopt
argumen CLI gaya-parsing di peti getop .
Bagi saya, getop selalu terasa terlalu rendah dan docopt.rs terlalu ajaib. Saya menginginkan sesuatu yang eksplisit dan langsung yang masih menyediakan semua fitur jika saya membutuhkannya.
Di sinilah clap-rs berguna.
Rasanya agak seperti argparse dari Python. Berikut ini contoh tampilannya:
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();
Anda dapat mengakses parameter Anda seperti:
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);
(Disalin dari dokumentasi resmi )
Pada versi 0.8 / 0.9, jalur yang benar ke fungsi args () adalah ::std::os::args
, yaitu:
fn main() {
let args: ~[~str] = ::std::os::args();
println(args[0]);
}
Tampaknya Rust masih cukup fluktuatif sekarang bahkan dengan IO standar, jadi ini mungkin menjadi usang cukup cepat.
Rust berubah lagi. os::args()
tidak digunakan lagi std::args()
. Tetapi std::args()
bukan sebuah array, ia mengembalikan iterator . Anda dapat mengulangi argumen baris perintah, tetapi tidak dapat mengaksesnya dengan subskrip.
http://doc.rust-lang.org/std/env/fn.args.html
Jika Anda ingin argumen baris perintah sebagai vektor string, ini akan berfungsi sekarang:
use std::env;
...
let args: Vec<String> = env::args().map(|s| s.into_string().unwrap()).collect();
Karat - belajar merangkul rasa sakit karena perubahan.
env::args().collect()
.
apa yang dikatakan @barjak berfungsi untuk string, tetapi jika Anda memerlukan argumen sebagai angka (dalam hal ini uint), Anda perlu mengonversi seperti ini:
fn main() {
let arg : ~[~str] = os::args();
match uint::from_str(arg[1]){
Some(x)=>io::println(fmt!("%u",someFunction(x))),
None=>io::println("I need a real number")
}
}
Lihat juga 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);
}
Pada versi Rust yang lebih baru (Rust> 0.10 / 11) sintaks array tidak berfungsi. Anda harus menggunakan metode get.
[Sunting] Sintaks array berfungsi (lagi) di malam hari. Jadi, Anda dapat memilih antara indeks pengambil atau array.
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. Saya kira itu ada di sana selama sebulan atau lebih. Lihat contoh ini .
Rust telah berevolusi sejak jawaban Calvin dari Mei 2013. Sekarang orang akan menguraikan argumen baris perintah dengan 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()
tidak ada lagi dan &args
harus digunakan sebagai gantinya.
The book Rust "Tidak ada stdlib" bab penutup cara mengakses parameter baris perintah (cara lain).
// Entry point for this program
#[start]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
0
}
Sekarang, contoh itu juga memiliki #![no_std]
yang saya pikir berarti bahwa biasanya, perpustakaan std akan memiliki titik masuk yang benar untuk biner Anda dan memanggil fungsi global yang disebut main()
. Opsi lain adalah 'nonaktifkan main
shim' dengan #![no_main]
. Yang jika saya tidak salah mengatakan kepada kompiler bahwa Anda mengambil kendali penuh atas bagaimana program Anda dimulai.
#![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
}
Saya tidak berpikir ini adalah cara yang 'baik' dalam melakukan sesuatu jika semua yang ingin Anda lakukan adalah membaca argumen baris perintah. The std::os
Modul disebutkan dalam jawaban lainnya tampaknya menjadi cara yang lebih baik dalam melakukan sesuatu. Saya mengirim jawaban ini demi penyelesaian.
println(args[0])