]>
Commit | Line | Data |
---|---|---|
13cf67c4 XL |
1 | ## Variables and Mutability |
2 | ||
94222f64 XL |
3 | As mentioned in the [“Storing Values with |
4 | Variables”][storing-values-with-variables]<!-- ignore --> section, by default | |
5 | variables are immutable. This is one of many nudges Rust gives you to write | |
6 | your code in a way that takes advantage of the safety and easy concurrency that | |
7 | Rust offers. However, you still have the option to make your variables mutable. | |
8 | Let’s explore how and why Rust encourages you to favor immutability and why | |
9 | sometimes you might want to opt out. | |
13cf67c4 XL |
10 | |
11 | When a variable is immutable, once a value is bound to a name, you can’t change | |
12 | that value. To illustrate this, let’s generate a new project called *variables* | |
13 | in your *projects* directory by using `cargo new variables`. | |
14 | ||
15 | Then, in your new *variables* directory, open *src/main.rs* and replace its | |
3c0e092e XL |
16 | code with the following code. This code won’t compile just yet, we’ll first |
17 | examine the immutability error. | |
13cf67c4 XL |
18 | |
19 | <span class="filename">Filename: src/main.rs</span> | |
20 | ||
21 | ```rust,ignore,does_not_compile | |
74b04a01 | 22 | {{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/src/main.rs}} |
13cf67c4 XL |
23 | ``` |
24 | ||
25 | Save and run the program using `cargo run`. You should receive an error | |
26 | message, as shown in this output: | |
27 | ||
f035d41b | 28 | ```console |
74b04a01 | 29 | {{#include ../listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/output.txt}} |
13cf67c4 XL |
30 | ``` |
31 | ||
32 | This example shows how the compiler helps you find errors in your programs. | |
3c0e092e | 33 | Compiler errors can be frustrating, but really they only mean your program |
13cf67c4 XL |
34 | isn’t safely doing what you want it to do yet; they do *not* mean that you’re |
35 | not a good programmer! Experienced Rustaceans still get compiler errors. | |
36 | ||
94222f64 XL |
37 | The error message indicates that the cause of the error is that you `` cannot |
38 | assign twice to immutable variable `x` ``, because you tried to assign a second | |
69743fb6 | 39 | value to the immutable `x` variable. |
13cf67c4 XL |
40 | |
41 | It’s important that we get compile-time errors when we attempt to change a | |
3c0e092e XL |
42 | value that’s designated as immutable because this very situation can lead to |
43 | bugs. If one part of our code operates on the assumption that a value will | |
44 | never change and another part of our code changes that value, it’s possible | |
45 | that the first part of the code won’t do what it was designed to do. The cause | |
46 | of this kind of bug can be difficult to track down after the fact, especially | |
47 | when the second piece of code changes the value only *sometimes*. The Rust | |
48 | compiler guarantees that when you state a value won’t change, it really won’t | |
49 | change, so you don’t have to keep track of it yourself. Your code is thus | |
50 | easier to reason through. | |
51 | ||
923072b8 FG |
52 | But mutability can be very useful, and can make code more convenient to write. |
53 | Although variables are immutable by default, you can make them mutable by adding | |
54 | `mut` in front of the variable name as you did in Chapter 2. Adding `mut` also | |
3c0e092e XL |
55 | conveys intent to future readers of the code by indicating that other parts of |
56 | the code will be changing this variable’s value. | |
13cf67c4 XL |
57 | |
58 | For example, let’s change *src/main.rs* to the following: | |
59 | ||
60 | <span class="filename">Filename: src/main.rs</span> | |
61 | ||
62 | ```rust | |
74b04a01 | 63 | {{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-02-adding-mut/src/main.rs}} |
13cf67c4 XL |
64 | ``` |
65 | ||
66 | When we run the program now, we get this: | |
67 | ||
f035d41b | 68 | ```console |
74b04a01 | 69 | {{#include ../listings/ch03-common-programming-concepts/no-listing-02-adding-mut/output.txt}} |
13cf67c4 XL |
70 | ``` |
71 | ||
a2a8927a | 72 | We’re allowed to change the value bound to `x` from `5` to `6` when `mut` |
04454e1e FG |
73 | is used. Ultimately, deciding whether to use mutability or not is up to you and |
74 | depends on what you think is clearest in that particular situation. | |
13cf67c4 | 75 | |
3c0e092e | 76 | ### Constants |
13cf67c4 | 77 | |
3c0e092e XL |
78 | Like immutable variables, *constants* are values that are bound to a name and |
79 | are not allowed to change, but there are a few differences between constants | |
80 | and variables. | |
13cf67c4 XL |
81 | |
82 | First, you aren’t allowed to use `mut` with constants. Constants aren’t just | |
3c0e092e XL |
83 | immutable by default—they’re always immutable. You declare constants using the |
84 | `const` keyword instead of the `let` keyword, and the type of the value *must* | |
85 | be annotated. We’re about to cover types and type annotations in the next | |
86 | section, [“Data Types,”][data-types]<!-- ignore --> so don’t worry about the | |
87 | details right now. Just know that you must always annotate the type. | |
13cf67c4 XL |
88 | |
89 | Constants can be declared in any scope, including the global scope, which makes | |
90 | them useful for values that many parts of code need to know about. | |
91 | ||
92 | The last difference is that constants may be set only to a constant expression, | |
94222f64 | 93 | not the result of a value that could only be computed at runtime. |
13cf67c4 | 94 | |
3c0e092e | 95 | Here’s an example of a constant declaration: |
13cf67c4 XL |
96 | |
97 | ```rust | |
94222f64 | 98 | const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3; |
13cf67c4 XL |
99 | ``` |
100 | ||
3c0e092e XL |
101 | The constant’s name is `THREE_HOURS_IN_SECONDS` and its value is set to the |
102 | result of multiplying 60 (the number of seconds in a minute) by 60 (the number | |
103 | of minutes in an hour) by 3 (the number of hours we want to count in this | |
104 | program). Rust’s naming convention for constants is to use all uppercase with | |
105 | underscores between words. The compiler is able to evaluate a limited set of | |
106 | operations at compile time, which lets us choose to write out this value in a | |
107 | way that’s easier to understand and verify, rather than setting this constant | |
108 | to the value 10,800. See the [Rust Reference’s section on constant | |
109 | evaluation][const-eval] for more information on what operations can be used | |
110 | when declaring constants. | |
94222f64 | 111 | |
13cf67c4 | 112 | Constants are valid for the entire time a program runs, within the scope they |
94222f64 XL |
113 | were declared in. This property makes constants useful for values in your |
114 | application domain that multiple parts of the program might need to know about, | |
115 | such as the maximum number of points any player of a game is allowed to earn or | |
116 | the speed of light. | |
13cf67c4 XL |
117 | |
118 | Naming hardcoded values used throughout your program as constants is useful in | |
119 | conveying the meaning of that value to future maintainers of the code. It also | |
120 | helps to have only one place in your code you would need to change if the | |
121 | hardcoded value needed to be updated in the future. | |
122 | ||
123 | ### Shadowing | |
124 | ||
3c0e092e XL |
125 | As you saw in the guessing game tutorial in [Chapter |
126 | 2][comparing-the-guess-to-the-secret-number]<!-- ignore -->, you can declare a | |
127 | new variable with the same name as a previous variable. Rustaceans say that the | |
128 | first variable is *shadowed* by the second, which means that the second | |
04454e1e FG |
129 | variable is what the compiler will see when you use the name of the variable. |
130 | In effect, the second variable overshadows the first, taking any uses of the | |
131 | variable name to itself until either it itself is shadowed or the scope ends. | |
132 | We can shadow a variable by using the same variable’s name and repeating the | |
133 | use of the `let` keyword as follows: | |
13cf67c4 XL |
134 | |
135 | <span class="filename">Filename: src/main.rs</span> | |
136 | ||
137 | ```rust | |
74b04a01 | 138 | {{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-03-shadowing/src/main.rs}} |
13cf67c4 XL |
139 | ``` |
140 | ||
04454e1e FG |
141 | This program first binds `x` to a value of `5`. Then it creates a new variable |
142 | `x` by repeating `let x =`, taking the original value and adding `1` so the | |
143 | value of `x` is then `6`. Then, within an inner scope created with the curly | |
144 | brackets, the third `let` statement also shadows `x` and creates a new | |
145 | variable, multiplying the previous value by `2` to give `x` a value of `12`. | |
94222f64 XL |
146 | When that scope is over, the inner shadowing ends and `x` returns to being `6`. |
147 | When we run this program, it will output the following: | |
13cf67c4 | 148 | |
f035d41b | 149 | ```console |
74b04a01 | 150 | {{#include ../listings/ch03-common-programming-concepts/no-listing-03-shadowing/output.txt}} |
13cf67c4 XL |
151 | ``` |
152 | ||
532ac7d7 | 153 | Shadowing is different from marking a variable as `mut`, because we’ll get a |
13cf67c4 XL |
154 | compile-time error if we accidentally try to reassign to this variable without |
155 | using the `let` keyword. By using `let`, we can perform a few transformations | |
156 | on a value but have the variable be immutable after those transformations have | |
157 | been completed. | |
158 | ||
159 | The other difference between `mut` and shadowing is that because we’re | |
160 | effectively creating a new variable when we use the `let` keyword again, we can | |
161 | change the type of the value but reuse the same name. For example, say our | |
162 | program asks a user to show how many spaces they want between some text by | |
3c0e092e | 163 | inputting space characters, and then we want to store that input as a number: |
13cf67c4 XL |
164 | |
165 | ```rust | |
74b04a01 | 166 | {{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-04-shadowing-can-change-types/src/main.rs:here}} |
13cf67c4 XL |
167 | ``` |
168 | ||
3c0e092e XL |
169 | The first `spaces` variable is a string type and the second `spaces` variable |
170 | is a number type. Shadowing thus spares us from having to come up with | |
171 | different names, such as `spaces_str` and `spaces_num`; instead, we can reuse | |
172 | the simpler `spaces` name. However, if we try to use `mut` for this, as shown | |
173 | here, we’ll get a compile-time error: | |
13cf67c4 XL |
174 | |
175 | ```rust,ignore,does_not_compile | |
74b04a01 | 176 | {{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/src/main.rs:here}} |
13cf67c4 XL |
177 | ``` |
178 | ||
179 | The error says we’re not allowed to mutate a variable’s type: | |
180 | ||
f035d41b | 181 | ```console |
74b04a01 | 182 | {{#include ../listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/output.txt}} |
13cf67c4 XL |
183 | ``` |
184 | ||
185 | Now that we’ve explored how variables work, let’s look at more data types they | |
186 | can have. | |
9fa01778 XL |
187 | |
188 | [comparing-the-guess-to-the-secret-number]: | |
189 | ch02-00-guessing-game-tutorial.html#comparing-the-guess-to-the-secret-number | |
190 | [data-types]: ch03-02-data-types.html#data-types | |
94222f64 XL |
191 | [storing-values-with-variables]: ch02-00-guessing-game-tutorial.html#storing-values-with-variables |
192 | [const-eval]: ../reference/const_eval.html |