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