Suche…


Einführung

Eigentum ist eines der wichtigsten Konzepte in Rust und in den meisten anderen Sprachen nicht vorhanden. Die Idee , dass ein Wert kann durch eine bestimmte Variable im Besitz sein ist oft sehr schwer zu verstehen, vor allem in Sprachen , in denen das Kopieren ist implizit, aber dieser Abschnitt wird die verschiedenen Ideen umgebende Eigentum überprüfen.

Syntax

  • Sei x: & T = ... // x ist eine unveränderliche Referenz
  • Sei x: & mut T = ... // x ist eine ausschließliche, veränderbare Referenz
  • sei _ = & mut foo; // foo veränderlich ausleihen (dh ausschließlich)
  • lass _ = & foo; // Leihen Sie sich unbestechlich
  • sei _ = foo; // foo verschieben (erfordert Besitz)

Bemerkungen

  • In wesentlich älteren Versionen von Rust (vor 1.0; Mai 2015) hatte eine Variable im Besitz einen Typ, der mit ~ beginnt. Sie können dies in sehr alten Beispielen sehen.

Eigentum und Ausleihe

Alle Werte in Rust haben genau einen Eigentümer. Der Eigentümer ist verantwortlich für dropping diesen Wert , wenn es den Bereich verlässt, und ist der einzige, der den Besitz des Wertes bewegen kann. Der Besitzer eines Werts kann Verweise darauf vergeben, indem er diesen Wert anderen Code entlehnt . Zu einem bestimmten Zeitpunkt kann es eine beliebige Anzahl von unveränderlichen Verweisen auf einen Wert geben:

let owned = String::from("hello");
// since we own the value, we may let other variables borrow it
let immutable_borrow1 = &owned;
// as all current borrows are immutable, we can allow many of them
let immutable_borrow2 = &owned;
// in fact, if we have an immutable reference, we are also free to
// duplicate that reference, since we maintain the invariant that
// there are only immutable references
let immutable_borrow3 = &*immutable_borrow2;

oder ein einzelner veränderlicher Verweis darauf ( ERROR einen Fehler bei der Kompilierung an):

// for us to borrow a value mutably, it must be mutable
let mut owned = String::from("hello");
// we can borrow owned mutably
let mutable_borrow = &mut owned;
// but note that we cannot borrow owned *again*
let mutable_borrow2 = &mut owned; // ERROR, already borrowed
// nor can we cannot borrow owned immutably
// since a mutable borrow is exclusive.
let immutable_borrow = &owned; // ERROR, already borrowed

Wenn ausstehende Verweise (entweder veränderlich oder unveränderlich) auf einen Wert vorhanden sind, kann dieser Wert nicht verschoben werden (dh, der Besitz wird weggegeben). Wir müssen sicherstellen, dass alle Referenzen zuerst gelöscht wurden, um einen Wert verschieben zu können:

let foo = owned; // ERROR, outstanding references to owned
let owned = String::from("hello");
{
    let borrow = &owned;
    // ...
} // the scope ends the borrow
let foo = owned; // OK, owned and not borrowed

Darlehen und Lebenszeiten

Alle Werte in Rust haben eine Lebensdauer . Die Lebensdauer eines Werts umfasst das Codesegment, von dem der Wert bis zum Ort des Verschiebens oder bis zum Ende des enthaltenen Bereichs eingeführt wird

{
    let x = String::from("hello"); //             +
    // ...                                        :
    let y = String::from("hello"); //      +      |
    // ...                                 :      :
    foo(x) // x is moved                   |      = x's lifetime
    // ...                                 :
} //                                       = y's lifetime

Wenn Sie einen Wert ausleihen, hat die resultierende Referenz eine Lebensdauer , die an die Lebensdauer des geliehenen Werts gebunden ist:

{
    let x = String::from("hello");
    let y = String::from("world");
    // when we borrow y here, the lifetime of the reference
    // stored in foo is equal to the lifetime of y
    // (i.e., between let y = above, to the end of the scope below)
    let foo = &y;
    // similarly, this reference to x is bound to the lifetime
    // of x --- bar cannot, for example, spawn a thread that uses
    // the reference beyond where x is moved below.
    bar(&x);
}

Besitz- und Funktionsaufrufe

Die meisten Fragen zum Besitz kommen beim Schreiben von Funktionen auf. Wenn Sie die Typen der Argumente einer Funktion angeben, können Sie auswählen, wie der Wert übergeben wird. Wenn Sie nur Lesezugriff benötigen, können Sie eine unveränderliche Referenz verwenden:

fn foo(x: &String) {
    // foo is only authorized to read x's contents, and to create
    // additional immutable references to it if it so desires.
    let y = *x; // ERROR, cannot move when not owned
    x.push_str("foo"); // ERROR, cannot mutate with immutable reference
    println!("{}", x.len()); // reading OK
    foo(x); // forwarding reference OK
}

Wenn foo das Argument ändern muss, sollte es eine ausschließliche, veränderbare Referenz enthalten:

fn foo(x: &mut String) {
    // foo is still not responsible for dropping x before returning,
    // nor is it allowed to. however, foo may modify the String.
    let x2 = *x; // ERROR, cannot move when not owned
    x.push_str("foo"); // mutating OK
    drop(*x); // ERROR, cannot drop value when not owned
    println!("{}", x.len()); // reading OK
}

Wenn Sie & oder &mut nicht angeben, sagen Sie, dass die Funktion den Besitz eines Arguments übernimmt. Dies bedeutet, dass foo nun auch für das Ablegen von x .

fn foo(x: String) {
    // foo may do whatever it wishes with x, since no-one else has
    // access to it. once the function terminates, x will be dropped,
    // unless it is moved away when calling another function.
    let mut x2 = x; // moving OK
    x2.push_str("foo"); // mutating OK
    let _ = &mut x2; // mutable borrow OK
    let _ = &x2; // immutable borrow OK (note that &mut above is dropped)
    println!("{}", x2.len()); // reading OK
    drop(x2); // dropping OK
}

Eigentum und die Copy-Eigenschaft

Einige Rust-Typen implementieren die Copy Eigenschaft. Typen, die Copy können verschoben werden, ohne den betreffenden Wert zu besitzen. Dies liegt daran, dass der Inhalt des Werts einfach Byte für Byte in den Speicher kopiert werden kann, um einen neuen identischen Wert zu erzeugen. Die meisten usize in Rust ( bool , usize , f64 usw.) sind Copy .

let x: isize = 42;
let xr = &x;
let y = *xr; // OK, because isize is Copy
// both x and y are owned here

Insbesondere sind Vec und String nicht Copy :

let x = Vec::new();
let xr = &x;
let y = *xr; // ERROR, cannot move out of borrowed content


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow