Zoeken…
Invoering
Syntaxis
- let x: & T = ... // x is een onveranderlijke referentie
- let x: & mut T = ... // x is een exclusieve, muteerbare referentie
- let _ = & mut foo; // foo leenbaar (dwz exclusief)
- let _ = & foo; // foo onveranderlijk lenen
- laat _ = foo; // foo verplaatsen (vereist eigendom)
Opmerkingen
- In veel oudere versies van Rust (vóór 1.0; mei 2015) had een variabele in eigendom een type dat begon met
~
. U kunt dit zien in zeer oude voorbeelden.
Eigendom en lenen
Alle waarden in Rust hebben precies één eigenaar. De eigenaar is verantwoordelijk voor het laten vallen van die waarde wanneer deze buiten het bereik valt en is de enige die het eigendom van de waarde kan verplaatsen . De eigenaar van een waarde kan verwijzingen ernaar weggeven door andere stukken code die waarde te laten lenen . Op elk willekeurig moment kan er een aantal onveranderlijke verwijzingen naar een waarde zijn:
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;
of een enkele veranderlijke verwijzing ernaar ( ERROR
geeft een compilatie-fout aan):
// 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
Als er uitstaande verwijzingen (veranderlijk of onveranderlijk) zijn naar een waarde, kan die waarde niet worden verplaatst (dat wil zeggen dat de eigendom ervan wordt weggegeven). We moeten ervoor zorgen dat alle referenties eerst zijn verwijderd om een waarde te kunnen verplaatsen:
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
Lenen en levens
Alle waarden in Rust hebben een leven lang . De levensduur van een waarde overspant het codesegment van de waarde die wordt geïntroduceerd naar waar deze wordt verplaatst, of het einde van het bereik
{
let x = String::from("hello"); // +
// ... :
let y = String::from("hello"); // + |
// ... : :
foo(x) // x is moved | = x's lifetime
// ... :
} // = y's lifetime
Wanneer u een waarde leent, heeft de resulterende referentie een levensduur die gekoppeld is aan de levensduur van de waarde die wordt geleend:
{
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);
}
Eigendom en functieaanroepen
De meeste vragen over eigendom komen naar boven bij het schrijven van functies. Wanneer u de typen argumenten van een functie opgeeft, kunt u kiezen hoe die waarde wordt doorgegeven. Als u alleen alleen-lezen toegang nodig hebt, kunt u een onveranderlijke verwijzing gebruiken:
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
}
Als foo
het argument moet wijzigen, moet het een exclusieve, veranderlijke referentie bevatten:
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
}
Als u geen &
of &mut
opgeeft, zegt u dat de functie eigenaar wordt van een argument. Dit betekent dat foo
nu ook verantwoordelijk is voor het laten vallen van 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
}
Eigendom en de eigenschap Kopiëren
Sommige Rust-typen implementeren de eigenschap Copy
. Typen die Copy
kunnen worden verplaatst zonder de waarde in kwestie te bezitten. Dit komt omdat de inhoud van de waarde eenvoudig byte-voor-byte in het geheugen kan worden gekopieerd om een nieuwe, identieke waarde te produceren. De meeste primitieven in Rust ( bool
, usize
, f64
, etc.) zijn Copy
.
let x: isize = 42;
let xr = &x;
let y = *xr; // OK, because isize is Copy
// both x and y are owned here
Met name zijn Vec
en String
niet Copy
:
let x = Vec::new();
let xr = &x;
let y = *xr; // ERROR, cannot move out of borrowed content