Veränderbarkeit, die Möglichkeit etwas zu ändern, funktioniert in Rust ein wenig anders als in anderen Programmiersprachen.
Standardmäßig sind Variablen nicht veränderbar:
```rust,ignore
let x = 5;
x = 6; // Fehler!
```
Wir können Veränderbarkeit mit dem Schlüsselwort `mut`, die Kurzform für "mutable" (englisch: veränderbar), einführen:
# #![allow(unused_variables)]
#fn main() {
let mut x = 5;
x = 6; // Kein Problem!
#}
Dies ist eine veränderbare [Variablenbindung][v].
Wenn eine Bindung veränderbar ist, bedeutet es,
dass du ändern kannst woran die Variablenbindung gebunden ist.
In dem oberen Beispiel ist es nicht so, dass sich der Wert in `x` ändert,
sondern dass sich die Bindung von `x` von einem `i32` zu einem Anderen geändert hat.
Du kannst auch eine [Referenz][ref] zu einer Variablenbindung mittels `&x` erstellen.
Wenn du aber die Referenz benutzen möchtest um die Variablenbindung zu ändern,
benötigst du eine *veränderbare* Referenz:
# #![allow(unused_variables)]
#fn main() {
let mut x = 5;
let y = &mut x;
#}
`y` ist eine unveränderbare Variablenbindung zu einer veränderbaren Referenz.
Das bedeutet, dass du `y` nicht zu etwas anderem binden kannst, z.B. `y = &mut z`.
Du kannst aber `y` benutzen um `x` an etwas anders zu binden, z.B. durch `*y = 5`.
Ein subtiler Unterschied.
Wenn du beides brauchst:
# #![allow(unused_variables)]
#fn main() {
let mut x = 5;
let mut y = &mut x;
#}
Jetzt kann `y` an einen anderen Wert gebunden werden und der Wert der referenziert wird,
kann geändert werden.
Es ist wichtig hervorzuheben, dass `mut` Teil eines [`Musters`][pattern] ist,
so dass du zu soetwas binden kannst:
# #![allow(unused_variables)]
#fn main() {
let (mut x, y) = (5, 6);
fn foo(mut x: i32) {
}
#}
In dem Beispiel ist `x` veränderbar aber nicht `y`.
# Innere und äußere Veränderbarkeit
Doch wenn wir sagen, etwas ist "unveränderlich" in Rust,
dann bedeutet das nicht, dass es sich nicht ändern kann:
wir meinen damit, dass dessen "äußere Veränderbarkeit" unveränderlich ist.
Betrachte als Beispiel [`Arc
`][arc]:
# #![allow(unused_variables)]
#fn main() {
use std::sync::Arc;
let x = Arc::new(5);
let y = x.clone();
#}
Wenn wir `clone()` aufrufen, muss das `Arc` seinen Referenzzähler aktualisieren.
Jedoch haben wir kein `mut` verwendet,
`x` ist eine unveränderliche Variablenbindung,
und wir haben nicht `&mut 5` oder soetwas benutzt.
Nun, was passiert hier?
Um das zu verstehen, müssen wir zurück zu den Kernprinzipien von Rust,
Speichersicherheit und der Mechanismus, mit dem dies garantiert wird,
[Besitz][ownership] und [Ausleihe][borrowing].
> Du hast entweder die eine oder die andere Art Ausleihe, aber nicht beide gleichzeitig:
>
> * eine oder mehrere Referenzen (`&T`) zu einer Resource,
> * exakt eine veränderbare Referenz (`&mut T`).
Nun, dies ist die wirkliche Definition von "Unveränderbarkeit".
Ist es sicher zwei Referenzen zu Etwas zu haben?
Im Falle von `Arc` ist es sicher.
Die Veränderung ist gekapselt im der Struktur selbst.
Sie ist nicht nach Außen sichtbar.
Aus diesem Grund wird `&T` durch `clone()` zurück gegeben.
Wenn es `&mut T` zurück geben würde, wäre das ein Problem.
Andere Typen, wie die in dem [`std::cell`][stdcell] Modul,
haben hingegen innere Veränderbarkeit:
# #![allow(unused_variables)]
#fn main() {
use std::cell::RefCell;
let x = RefCell::new(42);
let y = x.borrow_mut();
#}
`RefCell` gibt über die Methode `borrow_mut()`
eine `&mut` Referenz zu der inneren Bindung
zurück.
Ist das nicht gefährlich? Was ist, wenn wir folgendes tun:
use std::cell::RefCell;
let x = RefCell::new(42);
let y = x.borrow_mut();
let z = x.borrow_mut();
# (y, z);
Dies löst durchaus eine `panic` zur Laufzeit aus.
Das ist, was `RefCell` macht:
es setzt Rusts Regeln zum Ausleihen zur Laufzeit durch
und `panic!`t wenn sie gebrochen werden.
Das erlaubt es uns mit einem weiteren Aspekt von Rusts Regeln zur Veränderbarkeit
umzuhehen.
Lass uns aber ersteinmal über diesen Aspekt sprechen.
## Veränderbarkeit bei Feldern
Veränderbarkeit ist eine Eigenschaft einer Ausleihe (`&mut`)
oder einer Variablenbindung (`let mut`).
Das bedeutet zum Beispiel, dass du kein [Struct][struct]
mit einigen veränderbaren und einigen unveränderbaren Feldern haben kannst:
struct Point {
x: i32,
mut y: i32, // das geht nicht
}
Die Veränderbarkeit eines Struct ist in ihrer Bindung:
struct Point {
x: i32,
y: i32,
}
let mut a = Point { x: 5, y: 6 };
a.x = 10;
let b = Point { x: 5, y: 6};
b.x = 10; // error: cannot assign to immutable field `b.x`
Jedoch kann man mit Hilfe von [`Cell`][cell] Veränderbarkeit pro Feld nachbilden:
# #![allow(unused_variables)]
#fn main() {
use std::cell::Cell;
struct Point {
x: i32,
y: Cell<i32>,
}
let point = Point { x: 5, y: Cell::new(6) };
point.y.set(7);
println!("y: {:?}", point.y);
#}
Dies gibt `y: Cell { value: 7 }` aus.
Wir haben `y` erfolgreich verändert.