Rust Tuples
In the Rust programming language, tuples are a compound data type made of a sequence of elements of the same or of different type.
Tuples are similar to arrays. Arrays are also a compound data type, but all of the elements in an array must be of the same data type (i.e. all strings, or Booleans). Tuples are useful when a compound type is required whose elements have different types.
Tuples have a fixed length and are immutable by default. Tuples are also declared using the let keyword and can be made mutable using mut.
The simplest way to define a tuple is by using implicit declaration. In this case, we are allowing Rust to specify the data type of an element based on its’ actual value:
let my_tuple = ("Bill", 42); // Declaring a tuple
In the above example, we declared a tuple called ‘my_tuple’. It contains two elements: a string and an integer.
Tuples are an important compound data type in Rust, and there are many helpful operations that we can perform using them.
In this article, we will cover the details of using tuples in Rust.
Creating a Tuple in Rust
We can define a tuple using the let keyword. Element values are assigned using a parenthesis-based syntax.
Tuples can be defined either implicitly or explicitly.
Explicit definition means that we specify the data type of each element. Implicit definition means that we allow Rust to figure out the data type needed based on our input. We will cover both explicit and implicit tuple definition below.
Implicitly Define a Tuple
To implicitly define a tuple, we can simply specify the values of the tuple elements, and Rust will imply the data type. We saw an example of this earlier:
let my_tuple = ("Bill",42);
We didn’t need to tell Rust that “Bill” is a string, or that ’42’ is an integer. The compiler was able to figure out these details based on the values themselves.
Contrast this with an explicit definition below.
Explicitly Define a Tuple
To explicitly define a tuple, we can specify the data types of its’ elements. This reduces ambiguity and can help to prevent errors.
For example:
let my_tuple: (&str,i32) = ("Bill",42);
In this case, we are specifying the data types of the two elements in the tuple. The first is a string and the second is a 32 bit signed integer (i32).
Accessing Tuple Elements Via Tuple Indexing
The elements of a tuple often need to be accessed. In arrays, indexing is done with square bracket indexing. But in a tuple, indexing is accomplished using a dot ‘.’ notation:
tuple_name.index_number
As with other indexing methods, the index starts at zero (0), meaning that the first element of a tuple will have an index of 0.
For example, if we want to access the third element of my_tuple, we would use:
my_tuple.2
The values of tuple elements can be manipulated in various ways. For example, they can can be printed, or operated on similarly to variables.
fn main() {
let my_tuple = ("Bob",42,true);
let name = my_tuple.0;
let age = my_tuple.1;
let is_verified = my_tuple.2;
println!("Hi, {}! You are age {} and your verification status is {}", name,age,is_verified);
}
Standard Output:
Hi, Bob! You are age 42 and your verification status is true
Printing a Tuple
Printing with tuples is very similar to printing with arrays. Tuples are compound types, so printing can mean a few different things.
We can print a single element, multiple elements, or an entire tuple.
Printing a Single Tuple Element
We can print a single tuple element using its’ index with dot ‘.’ notation:
let my_tuple = ("Bill",42);
println!("Your name is: {}", my_tuple.0);
Standard Output:
Your name is: Bill
Printing Multiple Tuple Elements
Similarly, we can use standard indexing notation to print multiple elements, just as we would multiple variables:
let my_tuple = ("Bill",42);
println!("Your name is: {} and your age is: {}", my_tuple.0, my_tuple.1);
Standard Output: Your name is: Bill is your age is: 42
Printing a Full Tuple
We can use the debug trait {:?} to print a full tuple:
fn main() {
let my_tuple = ("Bill",42);
println!("{:?}", my_tuple);
}
Standard Output: ("Bill",42)
Mutable Tuples in Rust
Tuples are immutable by default, which means that once values are assigned to the elements of the array, they cannot be reassigned.
Note: A mutable tuple can’t change size, and elements can change value but not type.
Like variables and arrays, tuples can be made mutable using mut:
let mut my_tuple; // Declaring a mutable tuple
This allows us to change tuple element values after they have been defined:
// Declare and print a mutable tuple:
let mut my_tuple = ("Bill",42);
println!("{:?}",my_tuple);
// Change tuple element values:
my_tuple = ("Jim",26);
println!("{:?}",my_tuple);
Standard Output:
("Bill", 42)
("Jim", 26)
However, this does not allow us to increase the length of the tuple:
// Declare a mutable tuple with two elements:
let mut my_tuple = ("Bill",42);
// Attempt to add a third element:
my_tuple = ("Jim",26,true);
println!("{:?}",my_tuple);
Standard Error:
expected a tuple with 2 elements, found one with 3 elements
We also cannot change the data type of an element:
// Declare and print a mutable tuple:
let mut my_tuple = ("Bill",42);
// Attempt to change the type of the second element from integer to boolean:
my_tuple = ("Jim",true);
println!("{:?}",my_tuple);
Standard Error:
expected integer, found bool
Tuple vs. Array in Rust
The primary difference between a tuple and an array is that the elements of a tuple can be of any data type. In contrast, the elements of an array must all be of the same type.
This also means that a mutable tuple can hold data of any type. An array is limited to working with the type specified in its declaration.
Another difference between tuples and arrays is that tuples use parenthesis whereas arrays use square brackets.
Both tuples and arrays are declared using the keyword let. They are both immutable by default, and can be made mutable using mut in the declaration. Mutability is also limited in both tuples and arrays; their length can’t change nor can the element data type(s).