Packages und Crates

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 Packages and Crates. Dieser Lab ist ein Teil des Rust Buchs. Du kannst deine Rust-Fähigkeiten in LabEx üben.

In diesem Lab werden wir uns mit Packages und Crates befassen, wobei ein Crate die kleinste Code-Einheit ist, die der Rust-Compiler betrachtet und entweder ein binäres Crate oder ein Bibliothekscrate sein kann, und ein Package eine Sammlung von einem oder mehreren Crates ist, die eine bestimmte Funktionalität bietet.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust(("Rust")) -.-> rust/MemorySafetyandManagementGroup(["Memory Safety and Management"]) rust(("Rust")) -.-> rust/ProjectManagementandOrganizationGroup(["Project Management and Organization"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/MemorySafetyandManagementGroup -.-> rust/lifetime_specifiers("Lifetime Specifiers") rust/ProjectManagementandOrganizationGroup -.-> rust/module_system("Module System") subgraph Lab Skills rust/variable_declarations -.-> lab-100401{{"Packages und Crates"}} rust/function_syntax -.-> lab-100401{{"Packages und Crates"}} rust/expressions_statements -.-> lab-100401{{"Packages und Crates"}} rust/lifetime_specifiers -.-> lab-100401{{"Packages und Crates"}} rust/module_system -.-> lab-100401{{"Packages und Crates"}} end

Packages und Crates

Die ersten Teile des Modulsystems, das wir behandeln werden, sind Packages und Crates.

Ein Crate ist die kleinste Menge an Code, die der Rust-Compiler gleichzeitig betrachtet. Auch wenn Sie rustc statt cargo ausführen und eine einzelne Quellcode-Datei übergeben (wie wir es schon in "Schreiben und Ausführen eines Rust-Programms" getan haben), betrachtet der Compiler diese Datei als ein Crate. Crates können Module enthalten, und die Module können in anderen Dateien definiert sein, die mit dem Crate kompiliert werden, wie wir in den kommenden Abschnitten sehen werden.

Ein Crate kann in einer von zwei Formen vorliegen: ein binäres Crate oder ein Bibliothekscrate. Binäre Crates sind Programme, die Sie zu einem ausführbaren Programm kompilieren können, das Sie ausführen können, wie z. B. ein Befehlszeilenprogramm oder ein Server. Jeder muss eine Funktion namens main haben, die definiert, was passiert, wenn das ausführbare Programm ausgeführt wird. Alle Crates, die wir bisher erstellt haben, waren binäre Crates.

Bibliothekscrates haben keine main-Funktion und kompilieren nicht zu einem ausführbaren Programm. Stattdessen definieren sie Funktionalität, die mit mehreren Projekten geteilt werden soll. Beispielsweise bietet das rand-Crate, das wir im zweiten Kapitel verwendet haben, Funktionalität, um Zufallszahlen zu generieren. In den meisten Fällen, wenn Rust-Entwickler "Crate" sagen, meinen sie Bibliothekscrate, und sie verwenden "Crate" synonym mit dem allgemeinen Programmierkonzept einer "Bibliothek".

Die Crate-Wurzel ist eine Quellcode-Datei, von der der Rust-Compiler ausgeht und die das Wurzelmodul Ihres Crates bildet (wir werden Module im Abschnitt "Definieren von Modulen zur Kontrolle von Bereich und Privatsphäre" im Detail erklären).

Ein Package ist ein Bund von einem oder mehreren Crates, der eine bestimmte Funktionalität bietet. Ein Package enthält eine Cargo.toml-Datei, die beschreibt, wie diese Crates gebaut werden sollen. Cargo ist tatsächlich ein Package, das das binäre Crate für das Befehlszeilenwerkzeug enthält, das Sie bisher verwendet haben, um Ihren Code zu bauen. Das Cargo-Package enthält auch ein Bibliothekscrate, auf das das binäre Crate angewiesen ist. Andere Projekte können auf das Cargo-Bibliothekscrate zurückgreifen, um dieselbe Logik zu verwenden, die das Cargo-Befehlszeilenwerkzeug verwendet.

Ein Crate kann in einer von zwei Formen vorliegen: ein binäres Crate oder ein Bibliothekscrate. Ein Package kann beliebig viele binäre Crates enthalten, aber höchstens nur ein Bibliothekscrate. Ein Package muss mindestens ein Crate enthalten, egal ob es sich um ein Bibliothekscrate oder ein binäres Crate handelt.

Lassen Sie uns durchgehen, was passiert, wenn wir ein Package erstellen. Zunächst geben wir den Befehl cargo new my-project ein:

$ cargo new my-project
     Created binary (application) `my-project` package
$ ls my-project
Cargo.toml
src
$ ls my-project/src
main.rs

Nachdem wir cargo new my-project ausgeführt haben, verwenden wir ls, um zu sehen, was Cargo erstellt. Im Projektverzeichnis befindet sich eine Cargo.toml-Datei, die uns ein Package gibt. Es gibt auch ein src-Verzeichnis, das main.rs enthält. Öffnen Sie Cargo.toml in Ihrem Texteditor und bemerken Sie, dass src/main.rs nicht erwähnt wird. Cargo folgt der Konvention, dass src/main.rs die Crate-Wurzel eines binären Crates mit dem gleichen Namen wie das Package ist. Ebenso weiß Cargo, dass wenn das Package-Verzeichnis src/lib.rs enthält, das Package ein Bibliothekscrate mit dem gleichen Namen wie das Package enthält und src/lib.rs seine Crate-Wurzel ist. Cargo übergibt die Crate-Wurzel-Dateien an rustc, um die Bibliothek oder das binäre Programm zu bauen.

Hier haben wir ein Package, das nur src/main.rs enthält, was bedeutet, dass es nur ein binäres Crate namens my-project enthält. Wenn ein Package src/main.rs und src/lib.rs enthält, hat es zwei Crates: ein binäres und ein Bibliothekscrate, beide mit dem gleichen Namen wie das Package. Ein Package kann mehrere binäre Crates haben, indem Sie Dateien im src/bin-Verzeichnis platzieren: jede Datei wird ein separates binäres Crate sein.

Modules Cheat Sheet

Bevor wir auf die Details von Modulen und Pfaden zugehen, geben wir hier einen schnellen Überblick darüber, wie sich Module, Pfade, das use-Schlüsselwort und das pub-Schlüsselwort im Compiler verhalten und wie die meisten Entwickler ihren Code organisieren. Wir werden in diesem Kapitel Beispiele für jede dieser Regeln durchgehen, aber hier ist ein guter Bezugspunkt, um sich daran zu erinnern, wie die Module funktionieren.

  • Starten von der Crate-Wurzel: Wenn ein Crate kompiliert wird, sucht der Compiler zunächst in der Crate-Wurzel-Datei (gewöhnlich src/lib.rs für ein Bibliothekscrate oder src/main.rs für ein binäres Crate) nach Code, der kompiliert werden soll.
  • Deklarieren von Modulen: In der Crate-Wurzel-Datei können Sie neue Module deklarieren; sagen Sie, Sie deklarieren ein "garden"-Modul mit mod garden;. Der Compiler wird den Code des Moduls an diesen Stellen suchen:
  • Inline, innerhalb geschweifter Klammern, die das Semikolon nach mod garden ersetzen
  • In der Datei src/garden.rs
  • In der Datei src/garden/mod.rs
  • Deklarieren von Untermodulen: In jeder Datei außer der Crate-Wurzel können Sie Untermodule deklarieren. Beispielsweise können Sie mod vegetables; in src/garden.rs deklarieren. Der Compiler wird den Code des Untermoduls innerhalb des Verzeichnisses suchen, das für das übergeordnete Modul benannt ist, an diesen Stellen:
  • Inline, direkt nach mod vegetables, innerhalb geschweifter Klammern statt des Semikolons
  • In der Datei src/garden/vegetables.rs
  • In der Datei src/garden/vegetables/mod.rs
  • Pfade zu Code in Modulen: Wenn ein Modul Teil Ihres Crates ist, können Sie auf den Code in diesem Modul von überall anderen im selben Crate zugreifen, solange die Privatsphäre-Regeln es erlauben, indem Sie den Pfad zum Code verwenden. Beispielsweise würde ein Asparagus-Typ im Garten-Getreide-Modul bei crate::garden::vegetables::Asparagus gefunden werden.
  • Privat vs. öffentlich: Der Code innerhalb eines Moduls ist standardmäßig für seine übergeordneten Module privat. Um ein Modul öffentlich zu machen, deklarieren Sie es mit pub mod anstelle von mod. Um auch die Elemente innerhalb eines öffentlichen Moduls öffentlich zu machen, verwenden Sie pub vor ihrer Deklaration.
  • Das use-Schlüsselwort: Innerhalb eines Bereichs erzeugt das use-Schlüsselwort Kurzschlüsse zu Elementen, um die Wiederholung langer Pfade zu reduzieren. In jedem Bereich, in dem auf crate::garden::vegetables::Asparagus verwiesen werden kann, können Sie einen Kurzschluss mit use crate::garden::vegetables::Asparagus; erstellen, und ab dann müssen Sie nur Asparagus schreiben, um diesen Typ im Bereich zu verwenden.

Hier erstellen wir ein binäres Crate namens backyard, das diese Regeln veranschaulicht. Das Verzeichnis des Crates, ebenfalls benannt backyard, enthält diese Dateien und Verzeichnisse:

backyard
├── Cargo.lock
├── Cargo.toml
└── src
├── garden
│ └── vegetables.rs
├── garden.rs
└── main.rs

Die Crate-Wurzel-Datei in diesem Fall ist src/main.rs, und sie enthält:

use crate::garden::vegetables::Asparagus;

pub mod garden;

fn main() {
    let plant = Asparagus {};
    println!("I'm growing {:?}!", plant);
}

Die Zeile pub mod garden; sagt dem Compiler, den Code einzubeziehen, den er in src/garden.rs findet, der ist:

pub mod vegetables;

Hier bedeutet pub mod vegetables;, dass auch der Code in src/garden/vegetables.rs eingeschlossen wird. Der Code ist:

#[derive(Debug)]
pub struct Asparagus {}

Lassen Sie uns jetzt in die Details dieser Regeln eintauchen und sie in Aktion demonstrieren!

Zusammenfassung

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