Every value in Rust is of a certain data type, which tells Rust what kind of data is being specified so it knows how to work with that data.
In rust
, there are two data type subsets: scalar and compound.
Note:Rust is a statically typed language
, which means that it must know the types of all variables at compile time. The compiler can usually infer what type we want to use based on the value and how we use it.
In cases when many types are possible, such as when we converted a String
to a numeric type using parse
we must add a type annotation, like this:
let guess: u32 = "42".parse().expect("Not a number!");
If we don’t add the : u32 type annotation shown in the preceding code, Rust will display the error.
A scalar type represents a single value.
Rust has four primary scalar types: integers, floating-point numbers, Booleans, and characters.
An integer is a number without a fractional component.
Rust also has two primitive types for floating-point numbers, which are numbers with decimal points. Rust’s floating-point types are f32
and f64
, which are 32 bits and 64 bits in size, respectively.
Following is an example that shows floating-point numbers in action:
fn main() {
let x = 2.0; // f64
let y: f32 = 3.0; // f32
}
Rust supports the basic mathematical operations you’d expect for all the number types: addition, subtraction, multiplication, division, and remainder.
fn main() {
// addition
let sum = 5 + 10;
// subtraction
let difference = 95.5 - 4.3;
// multiplication
let product = 4 * 30;
// division
let quotient = 56.7 / 32.2;
let truncated = -5 / 3; // Results in -1
// remainder
let remainder = 43 % 5;
}
A Boolean type in Rust has two possible values: true
and false
. Booleans are one byte in size. The Boolean type in Rust is specified using bool.
For example:
fn main() {
let t = true;
let f: bool = false; // with explicit type annotation
}
Rust’s char type is the language’s most primitive alphabetic type.
For Example:
fn main() {
let c = 'z';
let z: char = 'ℤ'; // with explicit type annotation
let heart_eyed_cat = '😻';
}
We specify char
literals with single quotes, as opposed to string literals, which use double quotes.
Rust’s char type is four bytes in size and represents a Unicode Scalar Value, which means it can represent a lot more than just ASCII. Accented letters; Chinese, Japanese, and Korean characters; emoji; and zero-width spaces are all valid char values in Rust.
Compound types can group multiple values into one type. Rust has two primitive compound types: tuples and arrays.
A tuple is a general way of grouping together a number of values with a variety of types into one compound type. Tuples have a fixed length: once declared, they cannot grow or shrink in size.
We create a tuple by writing a comma-separated list of values inside parentheses. Each position in the tuple has a type, and the types of the different values in the tuple don’t have to be the same.
For Example:
fn main() {
let tup: (i32, f64, u8) = (500, 6.4, 1);
}
The variable tup
binds to the entire tuple because a tuple is considered a single compound element.
To get the individual values out of a tuple, we can use pattern matching to destructure a tuple value. For Example:
fn main() {
let tup = (500, 6.4, 1);
let (x, y, z) = tup;
println!("The value of y is: {y}");
}
This program first creates a tuple and binds it to the variable tup. It then uses a pattern with let to take tup and turn it into three separate variables, x, y, and z. This is called destructuring
because it breaks the single tuple into three parts. Finally, the program prints the value of y, which is 6.4.
We can also access a tuple element directly by using a period (.) followed by the index of the value we want to access.
For Example:
fn main() {
let x: (i32, f64, u8) = (500, 6.4, 1);
let five_hundred = x.0;
let six_point_four = x.1;
let one = x.2;
}
Another way to have a collection of multiple values is with an array. Unlike a tuple, every element of an array must have the same type. Unlike arrays in some other languages, arrays in Rust have a fixed length.
We write the values in an array as a comma-separated list inside square bracket.
fn main() {
let a = [1, 2, 3, 4, 5];
}
An array is a single chunk of memory of a known, fixed size that can be allocated on the stack. We can access elements of an array using indexing, like this:
fn main() {
let a = [1, 2, 3, 4, 5];
let first = a[0];
let second = a[1];
}