Zum Inhalt springen

Ownership

Welche der folgenden Optionen ist KEINE gültige Art der Behebung des Problems, eine Stack-Referenz aus einer Funktion zurückzugeben?

Ein Stack-Frame kann seine Lebenszeit nicht verlängern, daher ist dies keine gültige Lösung.


Angenommen, ein Programmierer hat versucht, die folgende Funktion zu schreiben:

/// Returns a person's name with "Ph.D." added as a title
fn award_phd(name: &String) -> String {
let mut name = *name;
name.push_str(", Ph.D.");
name
}

Der Rust-Compiler lehnt den Code mit folgendem 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`

Angesichts des angegebenen Zwecks der Funktion, welche der folgenden Optionen wäre die idiomatischste Korrektur für das Programm? Die Unterschiede zur obigen Funktion sind hervorgehoben.

Die Funktion soll den ursprünglichen Namen einer Person nicht ändern, daher wäre die Änderung des Typs von name zu &mut String oder String unangemessen. Die vom Compiler vorgeschlagene Lösung &*name ist nicht ausreichend – eine akzeptable Lösung ist es, die Daten mit name.clone() zu klonen und die lokale Kopie zu mutieren.


Angenommen, ein Programmierer hat versucht, die folgende Funktion zu schreiben:

/// Rounds all the floats in a vector to the nearest integer, in-place
fn round_in_place(v: &Vec<f32>) {
for n in v {
*n = n.round();
}
}

Der Rust-Compiler lehnt den Code mit folgendem Fehler ab:

error[E0594]: cannot assign to `*n`, which is behind a `&` reference
--> test.rs:4:9
|
3 | for n in v {
| - this iterator yields `&` references
4 | *n = n.round();
| ^^^^^^^^^^^^^^ `n` is a `&` reference, so the data it refers to cannot be written

Angesichts des angegebenen Zwecks der Funktion, welche der folgenden Optionen wäre die idiomatischste Korrektur für das Programm? Die Unterschiede zur obigen Funktion sind hervorgehoben.

Da diese Funktion einen Vektor in-place runden soll, wäre es nicht idiomatisch, eine neue Kopie desselben Vektors zurückzugeben (-> Vec<f32>) oder die Ownership des Vektors zu konsumieren (mut v: Vec<f32>). Die beste Lösung ist, die Typensignatur von &Vec<f32> zu &mut Vec<f32> zu ändern.