Befehlszeilenargumente akzeptieren

RustRustBeginner
Jetzt üben

This tutorial is from open-source community. Access the source code

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

Willkommen zu Akzeptieren von Befehlszeilenargumenten. Dieser Lab ist ein Teil des Rust Buchs. Du kannst deine Rust-Fähigkeiten in LabEx üben.

In diesem Lab werden wir ein neues Projekt namens "minigrep" erstellen, das zwei Befehlszeilenargumente akzeptiert: einen String, nach dem gesucht werden soll, und einen Dateipfad.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust(("Rust")) -.-> rust/DataStructuresandEnumsGroup(["Data Structures and Enums"]) rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/DataStructuresandEnumsGroup -.-> rust/method_syntax("Method Syntax") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("Traits for Operator Overloading") subgraph Lab Skills rust/variable_declarations -.-> lab-100418{{"Befehlszeilenargumente akzeptieren"}} rust/function_syntax -.-> lab-100418{{"Befehlszeilenargumente akzeptieren"}} rust/expressions_statements -.-> lab-100418{{"Befehlszeilenargumente akzeptieren"}} rust/method_syntax -.-> lab-100418{{"Befehlszeilenargumente akzeptieren"}} rust/operator_overloading -.-> lab-100418{{"Befehlszeilenargumente akzeptieren"}} end

Akzeptieren von Befehlszeilenargumenten

Lassen Sie uns wie immer mit cargo new ein neues Projekt erstellen. Wir werden unser Projekt minigrep nennen, um es vom grep-Tool zu unterscheiden, das Sie möglicherweise bereits auf Ihrem System haben.

$ cargo new minigrep
     Created binary (application) `minigrep` project
$ cd minigrep

Die erste Aufgabe besteht darin, dass minigrep seine zwei Befehlszeilenargumente akzeptiert: den Dateipfad und einen String, nach dem gesucht werden soll. Das heißt, wir möchten unser Programm mit cargo run ausführen können, zwei Bindestriche, um anzuzeigen, dass die folgenden Argumente für unser Programm und nicht für cargo sind, einen String, nach dem gesucht werden soll, und einen Pfad zu einer Datei, in der gesucht werden soll, wie folgt:

cargo run -- searchstring example-filename.txt

Derzeit kann das von cargo new generierte Programm keine Argumente verarbeiten, die wir ihm geben. Einige vorhandene Bibliotheken auf https://crates.io können dabei helfen, ein Programm zu schreiben, das Befehlszeilenargumente akzeptiert, aber da Sie gerade dieses Konzept lernen, implementieren wir diese Funktion selbst.

Lesen der Argumentwerte

Um es minigrep zu ermöglichen, die Werte der Befehlszeilenargumente zu lesen, die wir ihm übergeben, benötigen wir die std::env::args-Funktion, die in der Standardbibliothek von Rust zur Verfügung steht. Diese Funktion gibt einen Iterator über die an minigrep übergebenen Befehlszeilenargumente zurück. Wir werden Iteratoren im Kapitel 13 ausführlicher behandeln. Für jetzt müssen Sie nur zwei Details zu Iteratoren wissen: Iteratoren erzeugen eine Reihe von Werten, und wir können die collect-Methode auf einem Iterator aufrufen, um ihn in eine Sammlung wie einen Vektor zu verwandeln, der alle Elemente enthält, die der Iterator erzeugt.

Der Code in Listing 12-1 ermöglicht es Ihrem minigrep-Programm, alle an ihn übergebenen Befehlszeilenargumente zu lesen und die Werte dann in einen Vektor zu sammeln.

Dateiname: src/main.rs

use std::env;

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

Listing 12-1: Sammeln der Befehlszeilenargumente in einen Vektor und Ausgeben derselben

Zuerst bringen wir das std::env-Modul in den Gültigkeitsbereich mit einem use-Statement, damit wir seine args-Funktion verwenden können. Beachten Sie, dass die std::env::args-Funktion in zwei Ebenen von Modulen geschachtelt ist. Wie wir im Kapitel 7 diskutiert haben, wählen wir im Falle einer gewünschten Funktion, die in mehr als einem Modul geschachtelt ist, das übergeordnete Modul in den Gültigkeitsbereich, statt die Funktion. Dadurch können wir leicht andere Funktionen aus std::env verwenden. Es ist auch weniger zweideutig als das Hinzufügen von use std::env::args und dann das Aufrufen der Funktion nur mit args, da args leicht für eine Funktion verwechselt werden könnte, die in dem aktuellen Modul definiert ist.

Die args-Funktion und ungültiges Unicode

Beachten Sie, dass std::env::args einen Fehler auslösen wird, wenn irgendein Argument ungültiges Unicode enthält. Wenn Ihr Programm Argumente mit ungültigem Unicode akzeptieren muss, verwenden Sie stattdessen std::env::args_os. Diese Funktion gibt einen Iterator zurück, der OsString-Werte statt String-Werte erzeugt. Wir haben hier aus Einfachheit std::env::args gewählt, weil OsString-Werte je nach Plattform unterschiedlich sind und mit String-Werten umzugehen komplexer ist.

In der ersten Zeile von main rufen wir env::args auf und verwenden sofort collect, um den Iterator in einen Vektor zu verwandeln, der alle von dem Iterator erzeugten Werte enthält. Wir können die collect-Funktion verwenden, um viele Arten von Sammlungen zu erstellen, daher annotieren wir explizit den Typ von args, um anzugeben, dass wir einen Vektor von Strings möchten. Obwohl Sie in Rust sehr selten Typen annotieren müssen, ist collect eine Funktion, für die Sie es oft tun müssen, weil Rust nicht in der Lage ist, die Art der Sammlung zu inferieren, die Sie möchten.

Schließlich drucken wir den Vektor mit der Debug-Makro. Versuchen wir zuerst den Code ohne Argumente und dann mit zwei Argumenten auszuführen:

$ cargo run
--snip--
[src/main.rs:5] args = [
"target/debug/minigrep",
]
$ cargo run -- needle haystack
--snip--
[src/main.rs:5] args = [
"target/debug/minigrep",
"needle",
"haystack",
]

Beachten Sie, dass der erste Wert im Vektor "target/debug/minigrep" ist, was der Name unseres Binärprogramms ist. Dies stimmt mit dem Verhalten der Argumentliste in C überein und ermöglicht es Programmen, den Namen, unter dem sie aufgerufen wurden, in ihrer Ausführung zu verwenden. Es ist oft praktisch, auf den Programmnamen zugreifen zu können, falls Sie ihn in Nachrichten ausgeben möchten oder das Verhalten des Programms basierend auf dem Befehlszeilenalias ändern möchten, mit dem das Programm aufgerufen wurde. Aber für die Zwecke dieses Kapitels werden wir ihn ignorieren und nur die zwei benötigten Argumente speichern.

Speichern der Argumentwerte in Variablen

Das Programm kann derzeit auf die als Befehlszeilenargumente angegebenen Werte zugreifen. Jetzt müssen wir die Werte der beiden Argumente in Variablen speichern, damit wir die Werte im Rest des Programms verwenden können. Wir tun das in Listing 12-2.

Dateiname: src/main.rs

use std::env;

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

    let query = &args[1];
    let file_path = &args[2];

    println!("Searching for {}", query);
    println!("In file {}", file_path);
}

Listing 12-2: Erstellen von Variablen, um das Suchargument und den Dateipfadargument zu speichern

Wie wir gesehen haben, als wir den Vektor ausgegeben haben, nimmt der Programmname den ersten Wert im Vektor bei args[0] ein, daher beginnen wir die Argumente bei Index 1. Das erste Argument, das minigrep erhält, ist der String, nach dem wir suchen, daher legen wir eine Referenz auf das erste Argument in der Variable query ab. Das zweite Argument wird der Dateipfad sein, daher legen wir eine Referenz auf das zweite Argument in der Variable file_path ab.

Wir geben die Werte dieser Variablen vorübergehend aus, um zu beweisen, dass der Code wie gewünscht funktioniert. Führen wir dieses Programm erneut mit den Argumenten test und sample.txt aus:

$ cargo run -- test sample.txt
   Compiling minigrep v0.1.0 (file:///projects/minigrep)
    Finished dev [unoptimized + debuginfo] target(s) in 0.0s
     Running `target/debug/minigrep test sample.txt`
Searching for test
In file sample.txt

Super, das Programm funktioniert! Die Werte der Argumente, die wir benötigen, werden in die richtigen Variablen gespeichert. Später werden wir einige Fehlerbehandlungen hinzufügen, um bestimmte potenzielle Fehlerfälle zu behandeln, wie wenn der Benutzer keine Argumente angibt; für jetzt ignorieren wir diese Situation und arbeiten stattdessen an der Hinzufügung von Datei-lesefähigkeiten.

Zusammenfassung

Herzlichen Glückwunsch! Sie haben das Lab Akzeptieren von Befehlszeilenargumenten abgeschlossen. Sie können in LabEx weitere Labs absolvieren, um Ihre Fähigkeiten zu verbessern.