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