Відповіді:
Ви можете отримати доступ до аргументів командного рядка за допомогою функцій std::env::args
або std::env::args_os
. Обидві функції повертають ітератор над аргументами. Колишній ітератор над String
s (з яким легко працювати), але панікує, якщо один з аргументів не є дійсним unicode. Останнє повторює OsString
і не панікує.
Зауважте, що перший елемент ітератора - це назва самої програми (це умова у всіх основних ОС), тому перший аргумент - це власне другий ітераційний елемент.
Найпростіший спосіб вирішити результат args
- перетворити його на 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, макрос можна використовувати для автоматичного генерування структури та декодування на основі типу:
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 та документації є безліч повних робочих прикладів.
Відмова: Я один з авторів цієї бібліотеки.
У іржі getopt
аргумент CLI-стилю розбирається в ящику getopts .
Для мене getopts завжди відчував себе занадто низьким рівнем, а docopt.rs - занадто багато магії. Я хочу чогось явного і прямого, що все-таки надає всі функції, якщо вони мені потрібні.
Ось тут вам стане в нагоді clap-rs .
Це трохи схоже на аргументацію з Python. Ось приклад того, як це виглядає:
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]);
}
Здається, що Руст все ще досить мінливий з рівним стандартним 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();
Іржа - навчіться охоплювати біль змін.
env::args().collect()
.
те, що сказав @barjak, працює для рядків, але якщо вам потрібен аргумент у вигляді числа (в даному випадку - uint), вам потрібно перетворити так:
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")
}
}
Також перевірте 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.
[Редагувати] Синтаксис масиву працює (знову) вночі. Таким чином, ви можете вибрати між getter або індексом масиву.
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. Я здогадуюсь, що там є місяць або близько того. Дивіться цей приклад .
Іржа розвивалася з моменту відповіді Келвіна з травня 2013 року. Тепер аргументи командного рядка можна було б розібрати 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
слід використовувати замість цього.
У книзі Іржі "No 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])