Szukaj…


Wprowadzenie

Własność jest jedną z najważniejszych koncepcji w Rust i jest to coś, czego nie ma w większości innych języków. Pomysł, że dana wartość może należeć do konkretnej zmiennej, jest często dość trudny do zrozumienia, szczególnie w językach, w których kopiowanie jest dorozumiane, ale w tej części omówimy różne pomysły dotyczące własności.

Składnia

  • niech x: & T = ... // x jest niezmiennym odwołaniem
  • niech x: & mut T = ... // x jest wyłącznym, zmiennym odniesieniem
  • niech _ = & mut foo; // pożycz foo mutible (tj. wyłącznie)
  • niech _ = & foo; // pożycz foo niezmiennie
  • niech _ = foo; // move foo (wymaga własności)

Uwagi

  • W znacznie starszych wersjach Rust (przed 1.0; maj 2015) własna zmienna miała typ zaczynający się od ~ . Możesz to zobaczyć w bardzo starych przykładach.

Własność i pożyczki

Wszystkie wartości w Rust mają dokładnie jednego właściciela. Właściciel jest odpowiedzialny za upuszczenie tej wartości, gdy wykracza ona poza zakres, i jako jedyny może przenieść własność wartości. Właściciel wartości może podać do niej odniesienia , pozwalając innym fragmentom kodu pożyczyć tę wartość. W dowolnym momencie może istnieć dowolna liczba niezmiennych odniesień do wartości:

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;

lub pojedyncze zmienne odwołanie do niego ( ERROR oznacza błąd czasu kompilacji):

// 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

Jeśli istnieją nierozstrzygnięte odniesienia (zmienne lub niezmienne) do wartości, wartości tej nie można przenieść (tzn. Oddać jej własność). Musielibyśmy upewnić się, że wszystkie odwołania zostały najpierw usunięte, aby umożliwić przeniesienie wartości:

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

Pożyczki i wcielenia

Wszystkie wartości w Rust mają swoje życie . Okres istnienia wartości obejmuje segment kodu od wartości wprowadzanej do miejsca jej przeniesienia lub końca zakresu zawierającego

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

Ilekroć pożyczasz wartość, wynikowe odwołanie ma czas życia związany z czasem życia pożyczonej wartości:

{
    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);
}

Wywołania własności i funkcji

Większość pytań dotyczących własności pojawia się podczas pisania funkcji. Określając typy argumentów funkcji, możesz wybrać sposób przekazywania tej wartości. Jeśli potrzebujesz dostępu tylko do odczytu, możesz przyjąć niezmienne odwołanie:

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
}

Jeśli foo musi zmodyfikować argument, powinien przyjąć wyłączne, zmienne odwołanie:

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
}

Jeśli nie określisz ani & lub &mut , mówisz, że funkcja przejmie na własność argument. Oznacza to, że foo jest teraz również odpowiedzialny za upuszczenie 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
}

Własność i cecha Kopiuj

Niektóre typy rdzy implementują cechę Copy . Typy, które są Copy można przenosić bez posiadania danej wartości. Jest tak, ponieważ zawartość wartości można po prostu skopiować bajt po bajcie w pamięci, aby utworzyć nową, identyczną wartość. Większość prymitywów w Rust ( bool , usize , f64 itp.) To Copy .

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

W szczególności Vec i String nieCopy :

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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow