3 Vitually every non-’Hello World’ Rust program uses *variable bindings*. They
12 Putting `fn main() {` in each example is a bit tedious, so we’ll leave that out
13 in the future. If you’re following along, make sure to edit your `main()`
14 function, rather than leaving it off. Otherwise, you’ll get an error.
16 In many languages, this is called a *variable*, but Rust’s variable bindings
17 have a few tricks up their sleeves. For example the left-hand side of a `let`
18 expression is a ‘[pattern][pattern]’, not just a variable name. This means we
25 After this expression is evaluated, `x` will be one, and `y` will be two.
26 Patterns are really powerful, and have [their own section][pattern] in the
27 book. We don’t need those features for now, so we’ll just keep this in the back
28 of our minds as we go forward.
30 [pattern]: patterns.html
32 Rust is a statically typed language, which means that we specify our types up
33 front, and they’re checked at compile time. So why does our first example
34 compile? Well, Rust has this thing called ‘type inference’. If it can figure
35 out what the type of something is, Rust doesn’t require you to actually type it
38 We can add the type if we want to, though. Types come after a colon (`:`):
44 If I asked you to read this out loud to the rest of the class, you’d say “`x`
45 is a binding with the type `i32` and the value `five`.”
47 In this case we chose to represent `x` as a 32-bit signed integer. Rust has
48 many different primitive integer types. They begin with `i` for signed integers
49 and `u` for unsigned integers. The possible integer sizes are 8, 16, 32, and 64
52 In future examples, we may annotate the type in a comment. The examples will
61 Note the similarities between this annotation and the syntax you use with
62 `let`. Including these kinds of comments is not idiomatic Rust, but we'll
63 occasionally include them to help you understand what the types that Rust
66 By default, bindings are *immutable*. This code will not compile:
73 It will give you this error:
76 error: re-assignment of immutable variable `x`
81 If you want a binding to be mutable, you can use `mut`:
84 let mut x = 5; // mut x: i32
88 There is no single reason that bindings are immutable by default, but we can
89 think about it through one of Rust’s primary focuses: safety. If you forget to
90 say `mut`, the compiler will catch it, and let you know that you have mutated
91 something you may not have intended to mutate. If bindings were mutable by
92 default, the compiler would not be able to tell you this. If you _did_ intend
93 mutation, then the solution is quite easy: add `mut`.
95 There are other good reasons to avoid mutable state when possible, but they’re
96 out of the scope of this guide. In general, you can often avoid explicit
97 mutation, and so it is preferable in Rust. That said, sometimes, mutation is
98 what you need, so it’s not verboten.
100 Let’s get back to bindings. Rust variable bindings have one more aspect that
101 differs from other languages: bindings are required to be initialized with a
102 value before you're allowed to use them.
104 Let’s try it out. Change your `src/main.rs` file to look like this:
110 println!("Hello world!");
114 You can use `cargo build` on the command line to build it. You’ll get a
115 warning, but it will still print "Hello, world!":
118 Compiling hello_world v0.0.1 (file:///home/you/projects/hello_world)
119 src/main.rs:2:9: 2:10 warning: unused variable: `x`, #[warn(unused_variable)]
121 src/main.rs:2 let x: i32;
125 Rust warns us that we never use the variable binding, but since we never use
126 it, no harm, no foul. Things change if we try to actually use this `x`,
127 however. Let’s do that. Change your program to look like this:
133 println!("The value of x is: {}", x);
137 And try to build it. You’ll get an error:
141 Compiling hello_world v0.0.1 (file:///home/you/projects/hello_world)
142 src/main.rs:4:39: 4:40 error: use of possibly uninitialized variable: `x`
143 src/main.rs:4 println!("The value of x is: {}", x);
145 note: in expansion of format_args!
146 <std macros>:2:23: 2:77 note: expansion site
147 <std macros>:1:1: 3:2 note: in expansion of println!
148 src/main.rs:4:5: 4:42 note: expansion site
149 error: aborting due to previous error
150 Could not compile `hello_world`.
153 Rust will not let us use a value that has not been initialized. Next, let’s
154 talk about this stuff we've added to `println!`.
156 If you include two curly braces (`{}`, some call them moustaches...) in your
157 string to print, Rust will interpret this as a request to interpolate some sort
158 of value. *String interpolation* is a computer science term that means "stick
159 in the middle of a string." We add a comma, and then `x`, to indicate that we
160 want `x` to be the value we’re interpolating. The comma is used to separate
161 arguments we pass to functions and macros, if you’re passing more than one.
163 When you just use the curly braces, Rust will attempt to display the value in a
164 meaningful way by checking out its type. If you want to specify the format in a
165 more detailed manner, there are a [wide number of options available][format].
166 For now, we'll just stick to the default: integers aren't very complicated to
169 [format]: ../std/fmt/index.html