Das statische Konzept von Rust erkunden

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

In diesem Lab werden wir das Konzept von 'static in Rust besprechen.

Hinweis: Wenn das Lab keinen Dateinamen angibt, können Sie einen beliebigen Dateinamen verwenden. Beispielsweise können Sie main.rs verwenden und es mit rustc main.rs &&./main kompilieren und ausführen.


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/AdvancedTopicsGroup(["Advanced Topics"]) rust(("Rust")) -.-> rust/DataTypesGroup(["Data Types"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/DataTypesGroup -.-> rust/integer_types("Integer Types") rust/DataTypesGroup -.-> rust/string_type("String Type") rust/DataTypesGroup -.-> rust/type_casting("Type Conversion and Casting") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/MemorySafetyandManagementGroup -.-> rust/lifetime_specifiers("Lifetime Specifiers") rust/AdvancedTopicsGroup -.-> rust/traits("Traits") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("Traits for Operator Overloading") subgraph Lab Skills rust/variable_declarations -.-> lab-99211{{"Das statische Konzept von Rust erkunden"}} rust/integer_types -.-> lab-99211{{"Das statische Konzept von Rust erkunden"}} rust/string_type -.-> lab-99211{{"Das statische Konzept von Rust erkunden"}} rust/type_casting -.-> lab-99211{{"Das statische Konzept von Rust erkunden"}} rust/function_syntax -.-> lab-99211{{"Das statische Konzept von Rust erkunden"}} rust/expressions_statements -.-> lab-99211{{"Das statische Konzept von Rust erkunden"}} rust/lifetime_specifiers -.-> lab-99211{{"Das statische Konzept von Rust erkunden"}} rust/traits -.-> lab-99211{{"Das statische Konzept von Rust erkunden"}} rust/operator_overloading -.-> lab-99211{{"Das statische Konzept von Rust erkunden"}} end

Statisch

Rust hat einige reservierte Lebensdauerbezeichnungen. Eine davon ist 'static. Sie können es in zwei Situationen antrennen:

// Ein Verweis mit 'static Lebensdauer:
let s: &'static str = "hello world";

// 'static als Teil einer Trait-Bedingung:
fn generic<T>(x: T) where T: 'static {}

Beide sind verwandt, aber subtil unterschiedlich, und dies ist eine häufige Quelle der Verwirrung, wenn man Rust lernt. Hier sind einige Beispiele für jede Situation:

Verweislebensdauer

Als Verweislebensdauer gibt 'static an, dass die von dem Verweis bezeichneten Daten für die gesamte Lebensdauer des laufenden Programms existieren. Es kann jedoch immer noch auf eine kürzere Lebensdauer umgewandelt werden.

Es gibt zwei Möglichkeiten, eine Variable mit 'static Lebensdauer zu erstellen, und beide werden im schreibgeschützten Speicher des Binärprogramms gespeichert:

  • Erstellen Sie eine Konstante mit der static-Deklaration.
  • Erstellen Sie einen string-Literal, der den Typ &'static str hat.

Siehe folgendes Beispiel für eine Darstellung jeder Methode:

// Erstellen Sie eine Konstante mit 'static Lebensdauer.
static NUM: i32 = 18;

// Gibt einen Verweis auf `NUM` zurück, wobei seine `'static`
// Lebensdauer auf die des Eingabearguments umgewandelt wird.
fn coerce_static<'a>(_: &'a i32) -> &'a i32 {
    &NUM
}

fn main() {
    {
        // Erstellen Sie einen `string`-Literal und drucken Sie ihn:
        let static_string = "I'm in read-only memory";
        println!("static_string: {}", static_string);

        // Wenn `static_string` außerhalb des Gültigkeitsbereichs tritt, kann der Verweis
        // nicht mehr verwendet werden, aber die Daten verbleiben im Binärprogramm.
    }

    {
        // Erstellen Sie eine Ganzzahl, um sie für `coerce_static` zu verwenden:
        let lifetime_num = 9;

        // Wandeln Sie `NUM` in die Lebensdauer von `lifetime_num` um:
        let coerced_static = coerce_static(&lifetime_num);

        println!("coerced_static: {}", coerced_static);
    }

    println!("NUM: {} bleibt zugänglich!", NUM);
}

Trait-Bedingung

Als Trait-Bedingung bedeutet es, dass der Typ keine nicht-statischen Verweise enthält. Beispielsweise kann der Empfänger das Objekt so lange behalten, wie er möchte, und es wird nie ungültig, bis er es ableitet.

Es ist wichtig zu verstehen, dass dies bedeutet, dass alle eigenen Daten immer eine 'static Lebensdauerbedingung erfüllen, aber ein Verweis auf diese eigenen Daten erfüllt dies im Allgemeinen nicht:

use std::fmt::Debug;

fn print_it( input: impl Debug + 'static ) {
    println!( "'static value passed in is: {:?}", input );
}

fn main() {
    // i ist eine eigene Variable und enthält keine Verweise, daher ist es 'static:
    let i = 5;
    print_it(i);

    // Ups, &i hat nur die Lebensdauer, die durch den Gültigkeitsbereich von
    // main() definiert ist, daher ist es nicht 'static:
    print_it(&i);
}

Der Compiler wird Ihnen sagen:

error[E0597]: `i` does not live long enough
  --> src/lib.rs:15:15
   |
15 |     print_it(&i);
   |     ---------^^--
   |     |         |
   |     |         borrowed value does not live long enough
   |     argument requires that `i` is borrowed for `'static`
16 | }
   | - `i` dropped here while still borrowed

Zusammenfassung

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