]> git.proxmox.com Git - rustc.git/blame - src/doc/book/first-edition/src/mutability.md
New upstream version 1.19.0+dfsg1
[rustc.git] / src / doc / book / first-edition / src / mutability.md
CommitLineData
8bb4bdeb 1# Mutability
9346a6ac 2
bd371182
AL
3Mutability, the ability to change something, works a bit differently in Rust
4than in other languages. The first aspect of mutability is its non-default
5status:
6
7```rust,ignore
8let x = 5;
476ff2be 9x = 6; // Error!
bd371182
AL
10```
11
12We can introduce mutability with the `mut` keyword:
13
14```rust
15let mut x = 5;
16
476ff2be 17x = 6; // No problem!
bd371182
AL
18```
19
20This is a mutable [variable binding][vb]. When a binding is mutable, it means
21you’re allowed to change what the binding points to. So in the above example,
22it’s not so much that the value at `x` is changing, but that the binding
23changed from one `i32` to another.
24
25[vb]: variable-bindings.html
26
a7813a04 27You can also create a [reference][ref] to it, using `&x`, but if you want to use the reference to change it, you will need a mutable reference:
bd371182
AL
28
29```rust
30let mut x = 5;
31let y = &mut x;
32```
33
a7813a04 34[ref]: references-and-borrowing.html
bd371182 35
a7813a04 36`y` is an immutable binding to a mutable reference, which means that you can’t bind 'y' to something else (`y = &mut z`), but `y` can be used to bind `x` to something else (`*y = 5`). A subtle distinction.
bd371182
AL
37
38Of course, if you need both:
39
40```rust
41let mut x = 5;
42let mut y = &mut x;
43```
44
45Now `y` can be bound to another value, and the value it’s referencing can be
46changed.
47
48It’s important to note that `mut` is part of a [pattern][pattern], so you
49can do things like this:
50
51```rust
52let (mut x, y) = (5, 6);
53
54fn foo(mut x: i32) {
55# }
56```
57
a7813a04
XL
58Note that here, the `x` is mutable, but not the `y`.
59
bd371182
AL
60[pattern]: patterns.html
61
62# Interior vs. Exterior Mutability
63
64However, when we say something is ‘immutable’ in Rust, that doesn’t mean that
5bcae85e
SL
65it’s not able to be changed: we are referring to its ‘exterior mutability’ that
66in this case is immutable. Consider, for example, [`Arc<T>`][arc]:
bd371182
AL
67
68```rust
69use std::sync::Arc;
70
71let x = Arc::new(5);
72let y = x.clone();
73```
74
cc61c64b 75[arc]: ../../std/sync/struct.Arc.html
bd371182
AL
76
77When we call `clone()`, the `Arc<T>` needs to update the reference count. Yet
78we’ve not used any `mut`s here, `x` is an immutable binding, and we didn’t take
79`&mut 5` or anything. So what gives?
80
81To understand this, we have to go back to the core of Rust’s guiding
82philosophy, memory safety, and the mechanism by which Rust guarantees it, the
83[ownership][ownership] system, and more specifically, [borrowing][borrowing]:
84
85> You may have one or the other of these two kinds of borrows, but not both at
86> the same time:
b039eaaf 87>
e9174d1e
SL
88> * one or more references (`&T`) to a resource,
89> * exactly one mutable reference (`&mut T`).
bd371182
AL
90
91[ownership]: ownership.html
62682a34 92[borrowing]: references-and-borrowing.html#borrowing
bd371182
AL
93
94So, that’s the real definition of ‘immutability’: is this safe to have two
95pointers to? In `Arc<T>`’s case, yes: the mutation is entirely contained inside
96the structure itself. It’s not user facing. For this reason, it hands out `&T`
97with `clone()`. If it handed out `&mut T`s, though, that would be a problem.
98
99Other types, like the ones in the [`std::cell`][stdcell] module, have the
100opposite: interior mutability. For example:
101
102```rust
103use std::cell::RefCell;
104
105let x = RefCell::new(42);
106
107let y = x.borrow_mut();
108```
109
cc61c64b 110[stdcell]: ../../std/cell/index.html
bd371182
AL
111
112RefCell hands out `&mut` references to what’s inside of it with the
113`borrow_mut()` method. Isn’t that dangerous? What if we do:
114
115```rust,ignore
116use std::cell::RefCell;
117
118let x = RefCell::new(42);
119
120let y = x.borrow_mut();
121let z = x.borrow_mut();
122# (y, z);
123```
124
125This will in fact panic, at runtime. This is what `RefCell` does: it enforces
126Rust’s borrowing rules at runtime, and `panic!`s if they’re violated. This
127allows us to get around another aspect of Rust’s mutability rules. Let’s talk
128about it first.
129
130## Field-level mutability
131
132Mutability is a property of either a borrow (`&mut`) or a binding (`let mut`).
133This means that, for example, you cannot have a [`struct`][struct] with
134some fields mutable and some immutable:
135
136```rust,ignore
137struct Point {
138 x: i32,
476ff2be 139 mut y: i32, // Nope.
bd371182
AL
140}
141```
142
143The mutability of a struct is in its binding:
144
145```rust,ignore
146struct Point {
147 x: i32,
148 y: i32,
149}
150
151let mut a = Point { x: 5, y: 6 };
152
153a.x = 10;
154
7cac9316 155let b = Point { x: 5, y: 6 };
bd371182 156
476ff2be 157b.x = 10; // Error: cannot assign to immutable field `b.x`.
bd371182
AL
158```
159
160[struct]: structs.html
161
62682a34 162However, by using [`Cell<T>`][cell], you can emulate field-level mutability:
bd371182 163
62682a34 164```rust
bd371182
AL
165use std::cell::Cell;
166
167struct Point {
168 x: i32,
169 y: Cell<i32>,
170}
171
172let point = Point { x: 5, y: Cell::new(6) };
173
174point.y.set(7);
175
176println!("y: {:?}", point.y);
177```
178
cc61c64b 179[cell]: ../../std/cell/struct.Cell.html
62682a34 180
bd371182 181This will print `y: Cell { value: 7 }`. We’ve successfully updated `y`.