Veränderbarkeit

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.