Zoeken…


Invoering

Eigendom is een van de belangrijkste concepten in Rust, en het is iets dat niet aanwezig is in de meeste andere talen. Het idee dat een waarde eigendom kan zijn van een bepaalde variabele is vaak vrij moeilijk te begrijpen, vooral in talen waar kopiëren impliciet is, maar in dit gedeelte worden de verschillende ideeën over eigendom besproken.

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


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow