Ce face env::args
env::args() returnează un iterator peste argumentele programului, ca String-uri. Primul element este calea programului însuși, iar argumentele date de utilizator urmează după. Pentru cargo run -- Ana 3, iteratorul dă "target/debug/salut", "Ana", "3".
De obicei le aduni cu env::args().collect::<Vec<String>>() sau sari peste primul cu .skip(1). Dacă un argument nu este UTF-8 valid, args() intră în panică; varianta env::args_os() dă OsString și acceptă orice. Pentru opțiuni complicate (--ajutor, -v) se folosește de obicei crate-ul clap.
Ce returnează
Un iterator Args peste String.
Exemple
Exemplul 1: Program pornit fără argumente
Exemplul a rulat fără argumente, deci există doar numele programului (aici fișierul compilat se numește program) și se folosește valoarea implicită.
use std::env;
use std::path::Path;
fn main() {
let argumente: Vec<String> = env::args().collect();
println!("număr de argumente: {}", argumente.len());
let program = Path::new(&argumente[0]).file_name().and_then(|n| n.to_str()).unwrap_or("?");
println!("programul: {program}");
let nume = env::args().nth(1).unwrap_or_else(|| String::from("vizitator"));
println!("Salut, {nume}!");
}
Rezultat
număr de argumente: 1
programul: program
Salut, vizitator!
Exemplul 2: Argumente date de utilizator
Rezultatul este cel din terminal, după comanda cargo run -- Ana 3 (tot ce urmează după -- ajunge la program).
use std::env;
fn main() {
let argumente: Vec<String> = env::args().collect();
println!("argumente: {argumente:?}");
let nume = argumente.get(1).map(String::as_str).unwrap_or("vizitator");
let ori: u32 = argumente.get(2).and_then(|t| t.parse().ok()).unwrap_or(1);
for _ in 0..ori {
println!("Salut, {nume}!");
}
}
Rezultat (cargo run – Ana 3)
argumente: ["target/debug/salut", "Ana", "3"]
Salut, Ana!
Salut, Ana!
Salut, Ana!
Exemplul 3: Funcție de procesare testabilă
Funcția primește orice iterator de texte. În main îi dăm argumentele reale, iar pentru test o listă scrisă în cod.
use std::env;
fn citeste_optiuni(args: impl Iterator<Item = String>) -> (bool, Vec<String>) {
let mut detaliat = false;
let mut fisiere = Vec::new();
for a in args {
if a == "-v" || a == "--detaliat" {
detaliat = true;
} else {
fisiere.push(a);
}
}
(detaliat, fisiere)
}
fn main() {
println!("reale: {:?}", citeste_optiuni(env::args().skip(1)));
let test = ["-v", "note.txt", "orar.csv"].map(String::from);
println!("test: {:?}", citeste_optiuni(test.into_iter()));
}
Rezultat
reale: (false, [])
test: (true, ["note.txt", "orar.csv"])
Greșeli frecvente
- Citești
args[1]fără să verifici lungimea: dacă utilizatorul nu dă argumente, programul intră în panică (index out of bounds). Foloseșteargs.get(1). - Rulezi
cargo run Anafără--: Cargo poate interpreta argumentele ca opțiuni proprii. Scriecargo run -- Ana. - Uiți că primul argument este numele programului și numeri greșit argumentele.
Comenzi înrudite
env::var: Citește valoarea unei variabile de mediu (HOME, PATH, setări proprii); dă Err dacă nu există.process::exit: Oprește imediat programul cu codul de ieșire dat (0 = succes, altceva = eroare), fără să mai ruleze restul codului.Command: Pornește alt program (proces copil): new() alege programul, arg() și args() adaugă argumente.