Eigentümerschaft
i32 vs. String Kopieren
Abschnitt betitelt „i32 vs. String Kopieren“Welche der folgenden Aussagen erklärt am besten, warum ein i32 ohne Verschiebung kopiert werden kann, ein String jedoch nicht?
Wenn ein String ohne Verschiebung kopiert werden könnte, dann könnten zwei Variablen glauben, denselben String zu besitzen, was zu einer doppelten Freigabe führen würde.
Dereferenzierung String
Abschnitt betitelt „Dereferenzierung String“Der folgende Code-Snippet kompiliert nicht:
let s = String::from("Hello world");let s_ref = &s;let s2 = *s_ref;println!("{s2}");Welche der folgenden Aussagen beschreibt am besten das undefinierte Verhalten, das auftreten könnte, wenn dieses Programm ausgeführt werden dürfte?
Das println ist technisch sicher, da der String erst am Ende des aktuellen Gültigkeitsbereichs freigegeben wird. Aber dann tritt undefiniertes Verhalten auf, wenn der String im Namen von s und s2 zweimal freigegeben wird.
Mutables Borrowing Vektor
Abschnitt betitelt „Mutables Borrowing Vektor“Das folgende Programm kompiliert nicht:
fn copy_to_prev(v: &mut Vec<i32>, i: usize) { let n = &mut v[i]; *n = v[i - 1];}fn main() { let mut v = vec![1, 2, 3]; copy_to_prev(&mut v, 1);}Welche der folgenden Aussagen beschreibt am besten das undefinierte Verhalten, das auftreten könnte, wenn dieses Programm ausgeführt werden dürfte?
Dieses Programm ist sicher. Es könnte kein undefiniertes Verhalten auftreten, wenn es ausgeführt würde. (Wenn i außerhalb der Grenzen von v läge, würde Rust zur Laufzeit paniken, anstatt undefiniertes Verhalten zu verursachen.)
Das Problem ist, dass Rust nicht sicher weiß, dass v[i] und v[i - 1] sich auf verschiedene Elemente beziehen.
String Ownership Verschiebung
Abschnitt betitelt „String Ownership Verschiebung“Betrachten Sie diese Funktion, die eine vereinfachte Variante der Funktion aus dem vorherigen Quiz ist:
/// Fügt den Namen einer Person "Ph.D." hinzufn award_phd(name: &String) { let mut name = *name; name.push_str(", Ph.D.");}Der Rust-Compiler lehnt diese Funktion mit dem folgenden Fehler ab:
error[E0507]: cannot move out of `*name` which is behind a shared reference --> test.rs:3:20 |3 | let mut name = *name; | ^^^^^ | | | move occurs because `*name` has type `String`, which does not implement the `Copy` trait | help: consider borrowing here: `&*name`Angenommen, der Compiler hätte diese Funktion NICHT abgelehnt. Wählen Sie jedes (falls zutreffend) der folgenden Programme aus, das bei Ausführung möglicherweise undefiniertes Verhalten verursachen könnte. Wenn keines dieser Programme undefiniertes Verhalten verursachen könnte, dann wählen Sie “Keines dieser Programme”.
Die Anweisung let mut name = *name bewirkt, dass name die Ownership des Eingabestrings übernimmt. Der Aufrufer behält jedoch auch weiterhin die Ownership des Strings. Daher wird der String nach Beendigung von award_phd freigegeben. Jedes der oben genannten Programme weist daher undefiniertes Verhalten auf, da name schließlich ein zweites Mal freigegeben wird. Es spielt keine Rolle, ob name oder eine Referenz auf name nach dem Aufruf von award_phd gelesen wird.
Array-Zugriff und Borrowing
Abschnitt betitelt „Array-Zugriff und Borrowing“fn main() { let mut point = [0, 1]; let mut x = point[0]; let y = &mut point[1]; x += 1; *y += 1; println!("{} {}", point[0], point[1]);}Dieses Programm kompiliert, da die Bindung von x point[0] kopiert, wodurch y point[1] mutabel borgen kann. Die Mutation x += 1 beeinflusst point nicht, während die Mutation *y += 1 dies tut, sodass das Endergebnis 0 2 ist.