Pas öğretici komut satırından parametre alması nasıl açıklamıyor.fn main()
tüm örneklerde yalnızca boş bir parametre listesiyle gösterilir.
Komut satırı parametrelerine erişmenin doğru yolu nedir main
?
Pas öğretici komut satırından parametre alması nasıl açıklamıyor.fn main()
tüm örneklerde yalnızca boş bir parametre listesiyle gösterilir.
Komut satırı parametrelerine erişmenin doğru yolu nedir main
?
Yanıtlar:
Komut satırı bağımsız değişkenlerine std::env::args
veya std::env::args_os
işlevlerini kullanarak erişebilirsiniz . Her iki işlev de argümanların üzerinde bir yineleyici döndürür. Birincisi String
s ( üzerinde çalışmak kolay) üzerinden yinelenir, ancak argümanlardan biri geçerli unicode değilse panikler. İkincisi OsString
s üzerinde yinelenir ve asla panik yapmaz.
Yineleyicinin ilk öğesinin programın adı olduğunu unutmayın (bu, tüm büyük işletim sistemlerinde bir kuraldır), bu nedenle ilk argüman aslında ikinci yinelenen öğedir.
Sonucu ele almanın kolay bir yolu, args
onu aşağıdakilere dönüştürmektir Vec
:
use std::env;
fn main() {
let args: Vec<_> = env::args().collect();
if args.len() > 1 {
println!("The first argument is {}", args[1]);
}
}
Bu bağımsız değişkenlerle çalışmak için tüm standart yineleyici araç kutusunu kullanabilirsiniz. Örneğin, yalnızca ilk argümanı almak için:
use std::env;
fn main() {
if let Some(arg1) = env::args().nth(1) {
println!("The first argument is {}", arg1);
}
}
Komut satırı bağımsız değişkenlerini ayrıştırmak için crates.io'da kitaplıklar bulabilirsiniz :
Docopt , bir kullanım dizesinden sizin için ayrıştırıcı oluşturan Rust için de kullanılabilir. Rust'ta bir bonus olarak, yapıyı otomatik olarak oluşturmak ve tür tabanlı kod çözme yapmak için bir makro kullanılabilir:
docopt!(Args, "
Usage: cp [-a] SOURCE DEST
cp [-a] SOURCE... DIR
Options:
-a, --archive Copy everything.
")
Ve args ile alabilirsiniz:
let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit());
README ve dokümantasyonda birçok tam çalışma örneği vardır.
Feragatname: Bu kütüphanenin yazarlarından biriyim.
Rust, getopts kasasındagetopt
ayrıştırma tarzı CLI argümanına sahiptir .
Benim için getopts her zaman çok düşük seviye hissettim ve docopt.rs çok fazla sihirdi. İhtiyacım olursa hala tüm özellikleri sağlayan açık ve anlaşılır bir şey istiyorum.
Clap-r'lerin işe yaradığı yer burasıdır .
Python'dan biraz argparse gibi geliyor. İşte nasıl göründüğüne bir örnek:
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();
Parametrelerinize şu şekilde erişebilirsiniz:
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);
( Resmi belgelerden kopyalanmıştır )
0.8 / 0.9 sürümünden itibaren, işlev args () işlevine giden doğru yol ::std::os::args
, yani:
fn main() {
let args: ~[~str] = ::std::os::args();
println(args[0]);
}
Rust'un şu anda standart IO ile bile hala oldukça uçucu olduğu görülüyor, bu yüzden bu oldukça hızlı bir şekilde eski olabilir.
Rust tekrar değişti. os::args()
lehine itiraz edilmiştir std::args()
. Ancak std::args()
bir dizi değil, bir yineleyici döndürür . Komut satırı bağımsız değişkenleri üzerinden yineleme yapabilirsiniz, ancak bunlara aboneliklerle erişemezsiniz.
http://doc.rust-lang.org/std/env/fn.args.html
Komut satırı bağımsız değişkenlerini bir dizeler vektörü olarak istiyorsanız, şimdi çalışacaktır:
use std::env;
...
let args: Vec<String> = env::args().map(|s| s.into_string().unwrap()).collect();
Pas - değişimin acısını kucaklamayı öğrenin.
env::args().collect()
.
@barjak ne dedi dizeleri için çalışır, ancak bir sayı olarak argümana ihtiyacınız varsa (bu durumda bir uint) şöyle dönüştürmeniz gerekir:
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")
}
}
Ayrıca structopt'a göz atın:
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);
}
Daha yeni Rust sürümleri (Rust> 0.10 / 11) itibariyle dizi sözdizimi çalışmaz. Get yöntemini kullanmanız gerekir.
[Edit] Dizi sözdizimi (tekrar) gece çalışır. Böylece alıcı veya dizi dizini arasında seçim yapabilirsiniz.
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 üzerindeki indeksleme sözdizimini destekler . Sanırım bir ay kadar orada. Bu örneğe bakın .
Pas Şimdi biri ile komut satırı argümanları ayrıştırmak olurdu Mayıs 2013 den Calvin'in cevap beri gelişti 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()
artık mevcut değil ve &args
bunun yerine kullanılmalıdır.
Pas kitabı "Hayır stdlib" bölüm kapakları nasıl komut satırları parametreleri (başka şekilde) erişmek için.
// Entry point for this program
#[start]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
0
}
Şimdi, örnek, #![no_std]
normalde std kütüphanesinin ikili için gerçek giriş noktasına sahip olacağı ve denilen küresel bir işlevi çağıracağı anlamına geldiğini düşündüğüm de var main()
. Başka bir seçenek de ' main
şimi devre dışı bırakmak ' ile #![no_main]
. Hangi yanılmıyorsam derleyiciye programınızın nasıl başlatıldığı konusunda tam kontrol sahibi olduğunuzu söylüyor.
#![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
}
Tek yapmanız gereken komut satırı argümanlarını okumaksa, bunun bir şeyler yapmanın 'iyi' bir yolu olduğunu düşünmüyorum. std::os
Diğer yanıtlar sözü modül şeyler yapmanın çok daha iyi bir yol olarak görünmektedir. Bu cevabı tamamlama uğruna gönderiyorum.
println(args[0])