English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Rust Organization Management

Eine Programmiersprache, die den Code nicht organisieren kann, ist schwer zu vertiefen, fast keine Softwareprodukte werden aus einer Quelldatei kompiliert.

Bis jetzt hat dieses Tutorial alle Programme in einer Datei geschrieben, was hauptsächlich der Bequemlichkeit des Lernens der Syntax und Konzepte der Rust-Sprache dient.

Für ein Projekt ist es sehr wichtig, den Code zu organisieren.

In Rust gibt es drei wichtige Organisationskonzepte: Box, Paket, Modul.

Box(Crate)

"Box" ist eine Binärcode-Datei oder eine Bibliothekdatei, die im "Paket" existiert.

"Box" ist eine baumstruktur, deren Wurzel das Programm ist, das von den Quelldateien kompiliert wird, die beim Starten des Compilers ausgeführt werden.

Hinweis: "Binärcode-Datei" ist nicht unbedingt eine "ausführbare Binärcode-Datei", sie enthält nur Dateien, die Zielmaschinenprogrammiersprache enthalten, und der Dateiformat variiert je nach Kompilierungsumgebung.

Paket(Package)

Wenn wir den Befehl new von Cargo verwenden, um ein Rust-Projekt zu erstellen, wird im Projektverzeichnis eine Datei Cargo.toml erstellt. Die Substanz eines Projekts ist ein Paket, das von einer Datei Cargo.toml verwaltet werden muss, die die grundlegenden Informationen und Abhängigkeiten des Pakets beschreibt.

Ein Paket kann höchstens eine Bibliothek "Box" enthalten, kann aber beliebig viele Binärb"ös" enthalten, aber muss mindestens eine "Box" enthalten (ob Bibliothek oder Binärb"ös").

Nachdem Sie den Befehl cargo new verwendet haben, um ein Paket zu erstellen, wird unter src ein Source-Datei main.rs erstellt, Cargo definiert diesen Datei als Wurzel des Binärbusses, der nach der Kompilierung mit dem Paketnamen identisch ist.

Modul(Module)

Für ein Softwareprojekt sprechen wir oft nach den Organisationsnormen des verwendeten Programmierspraches, die Hauptstruktur der Organisationseinheiten ist oft ein Baum. Der Hauptorganisationseinheit der Java-Funktionsmodule ist die Klasse, und die Hauptmethode der Modulorganisation von JavaScript ist function.

Diese fortgeschrittenen Sprachorganisationsединицы können schichtweise enthalten, wie die Verzeichnisstruktur eines Dateisystems. Die Organisationseinheit in Rust ist das Modul (Module).

mod nation {
    mod government {
        fn govern() {}
    }
    mod congress {
        fn legislate() {}
    }
    mod court {
        fn judicial() {}
    }
}

Dies ist ein Text, der den Prozess eines Rechtsstaates beschreibt: Der Staat (nation) umfasst die Regierung (government), das Parlament (congress) und das Gericht (court), die分别具有行政、立法和司法的功能。Es kann in eine baumstruktur umgewandelt werden:

nation
 ├── government
 │ └── govern
 ├── congress
 │ └── legislate
 └── court
   └── judicial

In einem Dateisystem wird die Verzeichnisstruktur oft durch das Schrägstrichsymbol im Pfadstring zur Darstellung der Position von Objekten verwendet, der Pfadseparator in Rust ist ::.

Pfade werden in absolute und relative Pfade unterteilt. Der absolute Pfad beginnt mit dem Schlüsselwort "crate". Der relative Pfad beginnt mit den Schlüsselwörtern "self" oder "super" oder einem Identifikator. Zum Beispiel:

crate::nation::government::govern();

ist der absolute Pfad zur Funktion "govern", der relative Pfad kann wie folgt dargestellt werden:

nation::government::govern();

Jetzt können Sie versuchen, eine ähnliche Modulstruktur in einer Quelldatei zu definieren und im Hauptprogramm den Pfad zu verwenden.

Wenn Sie dies tun, werden Sie sicherlich feststellen, dass es einige falsche Stellen gibt: Der Module "government" und seine Funktionen sind privat (private), und Sie haben keine Berechtigung, auf sie zuzugreifen.

Zugriffsrechte

In Rust gibt es zwei einfache Zugriffsrechte: öffentlich (public) und privat (private).

Standardmäßig sind die Zugriffsrechte der Mitglieder eines Moduls privat, wenn keine Modifikatoren verwendet werden.

Um öffentliche Berechtigungen zu verwenden, muss das Schlüsselwort pub verwendet werden.

Für private Module kann man nur von Positionen auf gleicher Ebene oder niedrigeren Ebenen darauf zugreifen, nicht von außen.

mod nation {
    pub mod government {
        pub fn govern() {}
    }
    mod congress {
        pub fn legislate() {}
    }
    
    mod court {
        fn judical() {
            super::congress::legislate();
        }
    }
}
fn main() {
    nation::government::govern();
}

Dieses Programm kann kompiliert werden. Beachten Sie bitte die Methode des Zugriffs auf super im court-Modul.

Wenn ein Modul eine Struktur definiert, sind sowohl die Struktur als auch ihre Felder standardmäßig privat. Daher müssen Sie, um auf die Struktur und ihre Felder des Moduls zuzugreifen, das Schlüsselwort pub verwenden:

mod back_of_house {
    pub struct Breakfast {
        pub toast: String,
        sommerliche Frucht: String,
    }
    impl Breakfast {
        pub fn sommer(toast: &str) -> Breakfast {
            Breakfast {
                Brotscheibe: String::from(toast),
                sommerliche Frucht: String::from("Pflaumen"),
            }
        }
    }
}
pub fn eat_at_restaurant() {
    definiere ein neues "meal" = back_of_house::Breakfast::sommer("Rübenkraut");
    meal.toast = String::from("Weizen");
    println!("Ich möchte {} Brötchen haben, bitte", meal.toast);
}
fn main() {
    eat_at_restaurant()
}

Running Result:

Ich möchte einen Weizenbrötchen haben, bitte

Enum-Klassen können Felder enthalten, aber sie haben nicht die gleiche Eigenschaft:

mod SomeModule {
    pub enum Person {
        King {
            name: String
        },
        Quene
    }
}
fn main() {
    let person = SomeModule::Person::King{
        name: String::from("Blau")
    };
    match person {
        SomeModule::Person::King {name} => {
            println!("{}", name);
        }
        _ => {}
    }
}

Running Result:

Blau

Schwer zu entdeckende Module

Entwickler, die Java verwendet haben, mögen oft den äußeren class-Block sehr nicht - sein Name ist identisch mit dem Dateinamen, da er den Dateikontainer darstellt. Obwohl es lästig ist, müssen wir ihn immer noch einmal schreiben, um zu betonen "Diese Klasse ist die Klasse, die von der Datei enthalten ist".

Allerdings gibt es einige Vorteile: Zumindest ist es dem Entwickler klar, dass es ein Modul gibt, und man kann die Vererbungsbeziehung der Klassen klar beschreiben.

In Rust sind Module wie Java-Klassen verpackt, aber man kann am Anfang eines Dateis sofort eine Hauptfunktion schreiben. Wie erklären wir das?

Jeder Rust-Dateiinhalt ist ein "schwer zu entdecken"er Modul.

Lassen wir dies an zwei Dateien erläutern:

main.rs Datei

// main.rs
mod second_module;
fn main() {
    println!("Dies ist der Hauptmodul.");
    println!("{}", second_module::message());
}

second_module.rs Datei

// second_module.rs
pub fn message() -> String {
    String::from("Dies ist die") 2nd module.")
}

Running Result:

Dies ist der Hauptmodul.
Dies ist die 2nd module.

使用关键字

使用关键字能够将模块标识符引入当前作用域:

mod nation {
    pub mod government {
        pub fn govern() {}
    }
}
use crate::nation::government::govern;
fn main() {
    govern();
}

This program can be compiled successfully.

Because the use keyword imports the govern identifier into the current module, it can be used directly.

This solves the problem of long local module paths.

Of course, in some cases, there are two identical names that need to be imported, and we can use the as keyword to add aliases to identifiers:

mod nation {
    pub mod government {
        pub fn govern() {}
    }
    pub fn govern() {}
}
    
use crate::nation::government::govern;
use crate::nation::govern as nation_govern;
fn main() {
    nation_govern();
    govern();
}

Here are two govern functions, one under nation and one under government, we use as to alias the one under nation as nation_govern. Both names can be used at the same time.

The use keyword can be used with the pub keyword:

mod nation {
    pub mod government {
        pub fn govern() {}
    }
    pub use government::govern;
}
fn main() {
    nation::govern();
}

Reference Standard Library

Rust Official Standard Library Dictionary:https://doc.rust-lang.org/stable/std/all.html

After learning the concepts in this chapter, we can easily import system libraries to facilitate program development:

use std::f64::consts::PI;
fn main() {
    println!("{}", (PI / 2.0).sin());
}

Running Result:

1

All system library modules are imported by default, so you can easily use them by simply using the use keyword to simplify the path when using them.