]> git.proxmox.com Git - rustc.git/blob - src/doc/book/variable-bindings.md
03f17371de68d8aea04f76fe43fdd632e7b9bb07
[rustc.git] / src / doc / book / variable-bindings.md
1 % Variable Bindings
2
3 Virtually every non-'Hello World’ Rust program uses *variable bindings*. They
4 bind some value to a name, so it can be used later. `let` is
5 used to introduce a binding, like this:
6
7 ```rust
8 fn main() {
9 let x = 5;
10 }
11 ```
12
13 Putting `fn main() {` in each example is a bit tedious, so we’ll leave that out
14 in the future. If you’re following along, make sure to edit your `main()`
15 function, rather than leaving it off. Otherwise, you’ll get an error.
16
17 # Patterns
18
19 In many languages, a variable binding would be called a *variable*, but Rust’s
20 variable bindings have a few tricks up their sleeves. For example the
21 left-hand side of a `let` statement is a ‘[pattern][pattern]’, not a
22 variable name. This means we can do things like:
23
24 ```rust
25 let (x, y) = (1, 2);
26 ```
27
28 After this statement is evaluated, `x` will be one, and `y` will be two.
29 Patterns are really powerful, and have [their own section][pattern] in the
30 book. We don’t need those features for now, so we’ll keep this in the back
31 of our minds as we go forward.
32
33 [pattern]: patterns.html
34
35 # Type annotations
36
37 Rust is a statically typed language, which means that we specify our types up
38 front, and they’re checked at compile time. So why does our first example
39 compile? Well, Rust has this thing called ‘type inference’. If it can figure
40 out what the type of something is, Rust doesn’t require you to explicitly type
41 it out.
42
43 We can add the type if we want to, though. Types come after a colon (`:`):
44
45 ```rust
46 let x: i32 = 5;
47 ```
48
49 If I asked you to read this out loud to the rest of the class, you’d say “`x`
50 is a binding with the type `i32` and the value `five`.”
51
52 In this case we chose to represent `x` as a 32-bit signed integer. Rust has
53 many different primitive integer types. They begin with `i` for signed integers
54 and `u` for unsigned integers. The possible integer sizes are 8, 16, 32, and 64
55 bits.
56
57 In future examples, we may annotate the type in a comment. The examples will
58 look like this:
59
60 ```rust
61 fn main() {
62 let x = 5; // x: i32
63 }
64 ```
65
66 Note the similarities between this annotation and the syntax you use with
67 `let`. Including these kinds of comments is not idiomatic Rust, but we'll
68 occasionally include them to help you understand what the types that Rust
69 infers are.
70
71 # Mutability
72
73 By default, bindings are *immutable*. This code will not compile:
74
75 ```rust,ignore
76 let x = 5;
77 x = 10;
78 ```
79
80 It will give you this error:
81
82 ```text
83 error: re-assignment of immutable variable `x`
84 x = 10;
85 ^~~~~~~
86 ```
87
88 If you want a binding to be mutable, you can use `mut`:
89
90 ```rust
91 let mut x = 5; // mut x: i32
92 x = 10;
93 ```
94
95 There is no single reason that bindings are immutable by default, but we can
96 think about it through one of Rust’s primary focuses: safety. If you forget to
97 say `mut`, the compiler will catch it, and let you know that you have mutated
98 something you may not have intended to mutate. If bindings were mutable by
99 default, the compiler would not be able to tell you this. If you _did_ intend
100 mutation, then the solution is quite easy: add `mut`.
101
102 There are other good reasons to avoid mutable state when possible, but they’re
103 out of the scope of this guide. In general, you can often avoid explicit
104 mutation, and so it is preferable in Rust. That said, sometimes, mutation is
105 what you need, so it’s not verboten.
106
107 # Initializing bindings
108
109 Rust variable bindings have one more aspect that differs from other languages:
110 bindings are required to be initialized with a value before you're allowed to
111 use them.
112
113 Let’s try it out. Change your `src/main.rs` file to look like this:
114
115 ```rust
116 fn main() {
117 let x: i32;
118
119 println!("Hello world!");
120 }
121 ```
122
123 You can use `cargo build` on the command line to build it. You’ll get a
124 warning, but it will still print "Hello, world!":
125
126 ```text
127 Compiling hello_world v0.0.1 (file:///home/you/projects/hello_world)
128 src/main.rs:2:9: 2:10 warning: unused variable: `x`, #[warn(unused_variables)]
129 on by default
130 src/main.rs:2 let x: i32;
131 ^
132 ```
133
134 Rust warns us that we never use the variable binding, but since we never use
135 it, no harm, no foul. Things change if we try to actually use this `x`,
136 however. Let’s do that. Change your program to look like this:
137
138 ```rust,ignore
139 fn main() {
140 let x: i32;
141
142 println!("The value of x is: {}", x);
143 }
144 ```
145
146 And try to build it. You’ll get an error:
147
148 ```bash
149 $ cargo build
150 Compiling hello_world v0.0.1 (file:///home/you/projects/hello_world)
151 src/main.rs:4:39: 4:40 error: use of possibly uninitialized variable: `x`
152 src/main.rs:4 println!("The value of x is: {}", x);
153 ^
154 note: in expansion of format_args!
155 <std macros>:2:23: 2:77 note: expansion site
156 <std macros>:1:1: 3:2 note: in expansion of println!
157 src/main.rs:4:5: 4:42 note: expansion site
158 error: aborting due to previous error
159 Could not compile `hello_world`.
160 ```
161
162 Rust will not let us use a value that has not been initialized.
163
164 Let us take a minute to talk about this stuff we've added to `println!`.
165
166 If you include two curly braces (`{}`, some call them moustaches...) in your
167 string to print, Rust will interpret this as a request to interpolate some sort
168 of value. *String interpolation* is a computer science term that means "stick
169 in the middle of a string." We add a comma, and then `x`, to indicate that we
170 want `x` to be the value we’re interpolating. The comma is used to separate
171 arguments we pass to functions and macros, if you’re passing more than one.
172
173 When you use the curly braces, Rust will attempt to display the value in a
174 meaningful way by checking out its type. If you want to specify the format in a
175 more detailed manner, there are a [wide number of options available][format].
176 For now, we'll stick to the default: integers aren't very complicated to
177 print.
178
179 [format]: ../std/fmt/index.html
180
181 # Scope and shadowing
182
183 Let’s get back to bindings. Variable bindings have a scope - they are
184 constrained to live in a block they were defined in. A block is a collection
185 of statements enclosed by `{` and `}`. Function definitions are also blocks!
186 In the following example we define two variable bindings, `x` and `y`, which
187 live in different blocks. `x` can be accessed from inside the `fn main() {}`
188 block, while `y` can be accessed only from inside the inner block:
189
190 ```rust,ignore
191 fn main() {
192 let x: i32 = 17;
193 {
194 let y: i32 = 3;
195 println!("The value of x is {} and value of y is {}", x, y);
196 }
197 println!("The value of x is {} and value of y is {}", x, y); // This won't work
198 }
199 ```
200
201 The first `println!` would print "The value of x is 17 and the value of y is
202 3", but this example cannot be compiled successfully, because the second
203 `println!` cannot access the value of `y`, since it is not in scope anymore.
204 Instead we get this error:
205
206 ```bash
207 $ cargo build
208 Compiling hello v0.1.0 (file:///home/you/projects/hello_world)
209 main.rs:7:62: 7:63 error: unresolved name `y`. Did you mean `x`? [E0425]
210 main.rs:7 println!("The value of x is {} and value of y is {}", x, y); // This won't work
211 ^
212 note: in expansion of format_args!
213 <std macros>:2:25: 2:56 note: expansion site
214 <std macros>:1:1: 2:62 note: in expansion of print!
215 <std macros>:3:1: 3:54 note: expansion site
216 <std macros>:1:1: 3:58 note: in expansion of println!
217 main.rs:7:5: 7:65 note: expansion site
218 main.rs:7:62: 7:63 help: run `rustc --explain E0425` to see a detailed explanation
219 error: aborting due to previous error
220 Could not compile `hello`.
221
222 To learn more, run the command again with --verbose.
223 ```
224
225 Additionally, variable bindings can be shadowed. This means that a later
226 variable binding with the same name as another binding that is currently in
227 scope will override the previous binding.
228
229 ```rust
230 let x: i32 = 8;
231 {
232 println!("{}", x); // Prints "8"
233 let x = 12;
234 println!("{}", x); // Prints "12"
235 }
236 println!("{}", x); // Prints "8"
237 let x = 42;
238 println!("{}", x); // Prints "42"
239 ```
240
241 Shadowing and mutable bindings may appear as two sides of the same coin, but
242 they are two distinct concepts that can't always be used interchangeably. For
243 one, shadowing enables us to rebind a name to a value of a different type. It
244 is also possible to change the mutability of a binding. Note that shadowing a
245 name does not alter or destroy the value it was bound to, and the value will
246 continue to exist until it goes out of scope, even if it is no longer accessible
247 by any means.
248
249 ```rust
250 let mut x: i32 = 1;
251 x = 7;
252 let x = x; // x is now immutable and is bound to 7
253
254 let y = 4;
255 let y = "I can also be bound to text!"; // y is now of a different type
256 ```