]> git.lizzy.rs Git - rust.git/blob - src/doc/trpl/variable-bindings.md
Auto merge of #21401 - kballard:optimize-shrink-to-fit, r=nikomatsakis
[rust.git] / src / doc / trpl / variable-bindings.md
1 % Variable Bindings
2
3 The first thing we'll learn about are *variable bindings*. They look like this:
4
5 ```{rust}
6 fn main() {
7     let x = 5;
8 }
9 ```
10
11 Putting `fn main() {` in each example is a bit tedious, so we'll leave that out
12 in the future. If you're following along, make sure to edit your `main()`
13 function, rather than leaving it off. Otherwise, you'll get an error.
14
15 In many languages, this is called a *variable*. But Rust's variable bindings
16 have a few tricks up their sleeves. Rust has a very powerful feature called
17 *pattern matching* that we'll get into detail with later, but the left
18 hand side of a `let` expression is a full pattern, not just a variable name.
19 This means we can do things like:
20
21 ```{rust}
22 let (x, y) = (1, 2);
23 ```
24
25 After this expression is evaluated, `x` will be one, and `y` will be two.
26 Patterns are really powerful, but this is about all we can do with them so far.
27 So let's just keep this in the back of our minds as we go forward.
28
29 Rust is a statically typed language, which means that we specify our types up
30 front. So why does our first example compile? Well, Rust has this thing called
31 *type inference*. If it can figure out what the type of something is, Rust
32 doesn't require you to actually type it out.
33
34 We can add the type if we want to, though. Types come after a colon (`:`):
35
36 ```{rust}
37 let x: i32 = 5;
38 ```
39
40 If I asked you to read this out loud to the rest of the class, you'd say "`x`
41 is a binding with the type `i32` and the value `five`."
42
43 In future examples, we may annotate the type in a comment. The examples will
44 look like this:
45
46 ```{rust}
47 fn main() {
48     let x = 5; // x: i32
49 }
50 ```
51
52 Note the similarities between this annotation and the syntax you use with `let`.
53 Including these kinds of comments is not idiomatic Rust, but we'll occasionally
54 include them to help you understand what the types that Rust infers are.
55
56 By default, bindings are *immutable*. This code will not compile:
57
58 ```{ignore}
59 let x = 5;
60 x = 10;
61 ```
62
63 It will give you this error:
64
65 ```text
66 error: re-assignment of immutable variable `x`
67      x = 10;
68      ^~~~~~~
69 ```
70
71 If you want a binding to be mutable, you can use `mut`:
72
73 ```{rust}
74 let mut x = 5; // mut x: i32
75 x = 10;
76 ```
77
78 There is no single reason that bindings are immutable by default, but we can
79 think about it through one of Rust's primary focuses: safety. If you forget to
80 say `mut`, the compiler will catch it, and let you know that you have mutated
81 something you may not have intended to mutate. If bindings were mutable by
82 default, the compiler would not be able to tell you this. If you _did_ intend
83 mutation, then the solution is quite easy: add `mut`.
84
85 There are other good reasons to avoid mutable state when possible, but they're
86 out of the scope of this guide. In general, you can often avoid explicit
87 mutation, and so it is preferable in Rust. That said, sometimes, mutation is
88 what you need, so it's not verboten.
89
90 Let's get back to bindings. Rust variable bindings have one more aspect that
91 differs from other languages: bindings are required to be initialized with a
92 value before you're allowed to use them.
93
94 Let's try it out. Change your `src/main.rs` file to look like this:
95
96 ```{rust}
97 fn main() {
98     let x: i32;
99
100     println!("Hello world!");
101 }
102 ```
103
104 You can use `cargo build` on the command line to build it. You'll get a warning,
105 but it will still print "Hello, world!":
106
107 ```text
108    Compiling hello_world v0.0.1 (file:///home/you/projects/hello_world)
109 src/main.rs:2:9: 2:10 warning: unused variable: `x`, #[warn(unused_variable)] on by default
110 src/main.rs:2     let x: i32;
111                       ^
112 ```
113
114 Rust warns us that we never use the variable binding, but since we never use it,
115 no harm, no foul. Things change if we try to actually use this `x`, however. Let's
116 do that. Change your program to look like this:
117
118 ```{rust,ignore}
119 fn main() {
120     let x: i32;
121
122     println!("The value of x is: {}", x);
123 }
124 ```
125
126 And try to build it. You'll get an error:
127
128 ```{bash}
129 $ cargo build
130    Compiling hello_world v0.0.1 (file:///home/you/projects/hello_world)
131 src/main.rs:4:39: 4:40 error: use of possibly uninitialized variable: `x`
132 src/main.rs:4     println!("The value of x is: {}", x);
133                                                     ^
134 note: in expansion of format_args!
135 <std macros>:2:23: 2:77 note: expansion site
136 <std macros>:1:1: 3:2 note: in expansion of println!
137 src/main.rs:4:5: 4:42 note: expansion site
138 error: aborting due to previous error
139 Could not compile `hello_world`.
140 ```
141
142 Rust will not let us use a value that has not been initialized. Next, let's
143 talk about this stuff we've added to `println!`.
144
145 If you include two curly braces (`{}`, some call them moustaches...) in your
146 string to print, Rust will interpret this as a request to interpolate some sort
147 of value. *String interpolation* is a computer science term that means "stick
148 in the middle of a string." We add a comma, and then `x`, to indicate that we
149 want `x` to be the value we're interpolating. The comma is used to separate
150 arguments we pass to functions and macros, if you're passing more than one.
151
152 When you just use the curly braces, Rust will attempt to display the
153 value in a meaningful way by checking out its type. If you want to specify the
154 format in a more detailed manner, there are a [wide number of options
155 available](../std/fmt/index.html). For now, we'll just stick to the default:
156 integers aren't very complicated to print.