Suche…
Einführung
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