Shopping cart

0

Cart

  • 0 item

Nessun prodotto nel carrello.

All categories
 Corso Gratuito di Programmazione Rust Lezione 040 – Accettare gli argomenti della riga di comando

SE VUOI PRENDERE LA CERTIFICAZIONE PER QUESTO CORSO CLICCA QUI

Accettare Argomenti da Linea di Comando

Creiamo un nuovo progetto con, come sempre, cargo new. Chiameremo il nostro progetto minigrep per distinguerlo dallo strumento grep che potresti già avere nel tuo sistema.

sh

$ cargo new minigrep
Creato progetto binario (applicazione) `minigrep`
$ cd minigrep

Il primo compito è far sì che minigrep accetti i suoi due argomenti da linea di comando: il percorso del file e una stringa da cercare. In altre parole, vogliamo essere in grado di eseguire il nostro programma con cargo run, due trattini per indicare che gli argomenti successivi sono per il nostro programma piuttosto che per cargo, una stringa da cercare e il percorso a un file in cui cercare, come segue:

sh

$ cargo run -- stringaricerca percorsofile.txt

Al momento, il programma generato da cargo new non può processare gli argomenti che gli passiamo. Alcune librerie esistenti su crates.io possono aiutare nella scrittura di un programma che accetta argomenti da linea di comando, ma poiché stai solo imparando questo concetto, implementiamo questa capacità noi stessi. Lettura dei Valori degli Argomenti

Per consentire a minigrep di leggere i valori degli argomenti da linea di comando che gli passiamo, avremo bisogno della funzione std::env::args fornita nella libreria standard di Rust. Questa funzione restituisce un iteratore degli argomenti della riga di comando passati a minigrep. Copriremo gli iteratori completamente nel Capitolo 13. Per ora, devi solo sapere due dettagli sugli iteratori: gli iteratori producono una serie di valori e possiamo chiamare il metodo collect su un iteratore per trasformarlo in una collezione, come un vettore, che contiene tutti gli elementi prodotti dall’iteratore.

Il codice nella Lista 12-1 consente al tuo programma minigrep di leggere eventuali argomenti della riga di comando passati ad esso e quindi di raccogliere i valori in un vettore.

Filename: src/main.rs

rust

use std::env;

fn main() {
let args: Vec<String> = env::args().collect();
dbg!(args);
}

Prima di tutto, portiamo il modulo std::env in scope con una dichiarazione use in modo da poter utilizzare la sua funzione args. Nota che la funzione std::env::args è nidificata in due livelli di moduli. Come abbiamo discusso nel Capitolo 7, nei casi in cui la funzione desiderata è nidificata in più di un modulo, abbiamo scelto di portare il modulo padre in scope piuttosto che la funzione. Facendolo, possiamo facilmente utilizzare altre funzioni da std::env. È anche meno ambiguo rispetto all’aggiunta di use std::env::args e quindi chiamare la funzione solo con args, perché args potrebbe facilmente essere confuso con una funzione definita nel modulo corrente.

La Funzione args e Unicode Non Valido

Nota che std::env::args genererà un errore se un qualsiasi argomento contiene Unicode non valido. Se il tuo programma ha bisogno di accettare argomenti contenenti Unicode non valido, usa invece std::env::args_os. Questa funzione restituisce un iteratore che produce valori di tipo OsString invece di String. Abbiamo scelto di utilizzare std::env::args qui per semplicità, perché i valori di OsString differiscono per piattaforma e sono più complessi da gestire rispetto ai valori di String.

Sulla prima riga di main, chiamiamo env::args e utilizziamo immediatamente collect per trasformare l’iteratore in un vettore contenente tutti i valori prodotti dall’iteratore. Possiamo utilizzare la funzione collect per creare molti tipi di collezioni, quindi specifichiamo esplicitamente il tipo di args per specificare che vogliamo un vettore di stringhe. Anche se raramente abbiamo bisogno di annotare i tipi in Rust, collect è una funzione che devi spesso annotare perché Rust non è in grado di inferire il tipo di collezione desiderato.

Infine, stampiamo il vettore usando la macro debug. Proviamo prima a eseguire il codice senza argomenti e poi con due argomenti:

sh

$ cargo run
Compilazione in corso per minigrep v0.1.0 (file:///projects/minigrep)
Finito dev [non ottimizzato + informazioni di debug] target(s) in 0.61s
Esecuzione di `target/debug/minigrep`
[src/main.rs:5] args = [
"target/debug/minigrep",
]

$ cargo run -- ago fieno
Compilazione in corso per minigrep v0.1.0 (file:///projects/minigrep)
Finito dev [non ottimizzato + informazioni di debug] target(s) in 1.57s
Esecuzione di `target/debug/minigrep ago fieno`
[src/main.rs:5] args = [
"target/debug/minigrep",
"ago",
"fieno",
]

Nota che il primo valore nel vettore è “target/debug/minigrep”, che è il nome del nostro binario. Questo corrisponde al comportamento della lista degli argomenti in C, che consente ai programmi di utilizzare il nome con cui sono stati chiamati nella loro esecuzione. È spesso conveniente avere accesso al nome del programma nel caso in cui si voglia stamparlo in messaggi o cambiare il comportamento del programma in base a quale alias della riga di comando è stato utilizzato per chiamare il programma. Ma per i fini di questo capitolo, lo ignoreremo e salveremo solo i due argomenti di cui abbiamo bisogno. Salvare i Valori degli Argomenti in Variabili

Il programma attualmente è in grado di accedere ai valori specificati come argomenti della riga di comando. Ora dobbiamo salvare i valori dei due argomenti in variabili in modo da poterli utilizzare nel resto del programma. Lo facciamo nella Lista 12-2.

Filename: src/main.rs

rust

use std::env; fn main() {
let args: Vec<String> = env::args().collect(); let query = &args[1];
let file_path = &args[2];

println!("Sto cercando {}", query);
println!("Nel file {}", file_path);
}

Come abbiamo visto quando abbiamo stampato il vettore, il nome del programma occupa il primo valore nel vettore a args[0], quindi stiamo iniziando gli argomenti all’indice 1. Il primo argomento che minigrep prende è la stringa che stiamo cercando, quindi mettiamo un riferimento al primo argomento nella variabile query. Il secondo argomento sarà il percorso del file, quindi mettiamo un riferimento al secondo argomento nella variabile file_path.

Stampiamo temporaneamente i valori di queste variabili per dimostrare che il codice sta funzionando come intendiamo. Eseguiamo di nuovo questo programma con gli argomenti test e sample.txt:

sh

$ cargo run -- test sample.txt
Compilazione in corso per minigrep v0.1.0 (file:///projects/minigrep)
Finito dev [non ottimizzato + informazioni di debug] target(s) in 0.0s
Esecuzione di `target/debug/minigrep test sample.txt`
Sto cercando test
Nel file sample.txt

Ottimo, il programma funziona! I valori degli argomenti di cui abbiamo bisogno vengono salvati nelle variabili corrette. Più tardi aggiungeremo una gestione degli errori per gestire determinate situazioni erronee potenziali, come quando l’utente non fornisce alcun argomento; per ora, ignoreremo quella situazione e lavoreremo invece sull’aggiunta delle capacità di lettura dei file.

Leave a Reply

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *