Hier sind zwei Funktionssignaturen, die ich in der Rust-Dokumentation gesehen habe:
fn modify_foo(mut foo: Box<i32>) { *foo += 1; *foo }
fn modify_foo(foo: &mut i32) { *foo += 1; *foo }
Warum die unterschiedliche Platzierung von mut
?
Es scheint, dass die erste Funktion auch als deklariert werden könnte
fn modify_foo(foo: mut Box<i32>) { /* ... */ }
const
undpointee
Konstante .Antworten:
mut foo: T
bedeutet, dass Sie eine Variable namensfoo
a habenT
. Sie können ändern, worauf sich die Variable bezieht :let mut val1 = 2; val1 = 3; // OK let val2 = 2; val2 = 3; // error: re-assignment of immutable variable
Auf diese Weise können Sie auch Felder einer Struktur ändern, die Sie besitzen:
struct Monster { health: u8 } let mut orc = Monster { health: 93 }; orc.health -= 54; let goblin = Monster { health: 28 }; goblin.health += 10; // error: cannot assign to immutable field
foo: &mut T
bedeutet, dass Sie eine Variable haben, die auf (&
) einen Wert verweist, und Sie dürfen (mut
) den referenzierten Wert ändern (einschließlich Felder, wenn es sich um eine Struktur handelt):let val1 = &mut 2; *val1 = 3; // OK let val2 = &2; *val2 = 3; // error: cannot assign to immutable borrowed content
Beachten Sie, dass dies
&mut
nur mit einer Referenz sinnvollfoo: mut T
ist - keine gültige Syntax. Sie können die beiden Qualifikationsmerkmale (let mut a: &mut T
) auch kombinieren , wenn dies sinnvoll ist.quelle
int const*
gegenint *const
verschiedene Dinge zu erreichen.mut
bei einer Bindung innerhalb der Struktur mutieren können (wenn es sich um eine Struktur handelt).&mut Type
als&(mut Type)
, sondern als denken(&mut) Type
. Das Schlüsselwortmut
wird in Typen im Allgemeinen nicht verwendet, es wird jedoch eine Referenzart aufgerufen&mut
.const
Felder. Dies ist sicher, da Rust garantiert, wenn Sie etwas mutieren können, niemand anderes es gleichzeitig lesen oder mutieren kann.&T
und&mut T
als Zucker fürRef<T>
undRefMut<T>
vorstellen (Typen, die ich gerade erfunden habe).Wenn Sie aus C / C ++ kommen, kann es auch hilfreich sein, sich das grundsätzlich so vorzustellen:
// Rust C/C++ a: &T == const T* const a; // can't mutate either mut a: &T == const T* a; // can't mutate what is pointed to a: &mut T == T* const a; // can't mutate pointer mut a: &mut T == T* a; // can mutate both
Sie werden feststellen, dass dies Umkehrungen voneinander sind. C / C ++ verfolgt einen "Blacklist" -Ansatz. Wenn Sie möchten, dass etwas unveränderlich ist, müssen Sie dies explizit sagen, während Rust einen "Whitelist" -Ansatz verwendet. Wenn Sie möchten, dass etwas veränderlich ist, müssen Sie dies explizit sagen.
quelle
&mut T
Verweise auch analog zuT* restrict
Zeigern in C sind: Sie dürfen nicht mit einem Alias versehen sein.&T
Referenzen haben keine solche Einschränkung und es gibt keinen Referenztyp analog zu nichtrestrict
qualifiziertenT*
Zeigern.