Step 4 of 6
Types: annotations and inference
Every value in Rust has a type: the kind of value it is, which decides what you can do with it. Here are the basic ones (you've already used the first and the last):
| Value | Type | What it is |
|---|---|---|
120 |
i32 |
a whole number (an integer) |
3.5 |
f64 |
a number with a fraction (a floating-point number) |
true, false |
bool |
a yes/no value (a Boolean) |
'R' |
char |
one character, in single quotes |
"Ferris" |
&str |
a piece of text (a string slice), in double quotes |
Rust is statically typed: every variable's type is known when the program is compiled, and it never changes. But you rarely have to write the type, because the compiler works it out from the value. That's type inference. When you want to, you can write it yourself with a type annotation: a colon and the type after the name.
fn main() {
let lives: i32 = 3;
let speed: f64 = 2.5;
let is_boss: bool = false;
let grade: char = 'A';
let name: &str = "Ferris";
println!("{} {} {} {} {}", lives, speed, is_boss, grade, name);
}
3 2.5 false A Ferris
Without annotations, a whole number like 3 becomes an i32 and a number with a decimal point like 2.5 becomes an f64. The next module covers the number types in detail (there are several sizes).
Why annotate if the compiler can infer?
- To choose a type other than the default (you'll want bigger or non-negative integer types in the next module).
- To state your intent, so the compiler reports a mistake right where it happens.
- Some values could be several types, and the compiler needs you to pick one (you'll see this when reading numbers from input).
The annotation is a promise
The compiler checks that the value matches the type you wrote:
fn main() {
let count: i32 = "five";
println!("{}", count);
}
error[E0308]: mismatched types
--> src/main.rs:2:22
|
2 | let count: i32 = "five";
| --- ^^^^^^ expected `i32`, found `&str`
| |
| expected due to this
E0308 "mismatched types" is the error you'll see most often in Rust. It always tells you what was expected and what was found.
Common mistakes
let count: i32 = 3.0;:3.0is a float, not an integer, even though it's a whole number. Write3.- Text in single quotes:
'Ferris'is an error. Single quotes hold exactly onechar; text goes in double quotes. - Type before the name, as in C or Java (
let i32 count). In Rust the name comes first, then: type.
Your task
Fill in each variable's type so the program compiles and prints 21.5 true.
Challenge 2
The annotations are right, but the two values don't match their types. Fix the values (keep both annotations) so the program prints 3 lives, symbol @.
Challenge 3
Create a character profile with four variables, each with an explicit type annotation: name (&str) set to "Crabby", level (i32) set to 7, health (f64) set to 88.5 and online (bool) set to true. Print them on one line:
Crabby lvl 7 hp 88.5 online true