Rust Tuple Structs
In Rust, tuple structs are a type of hybrid struct that combine the attributes of structs and tuples. They are often considered to be named tuples.
Although they combine elements of both structs and tuples, tuple structs are in fact one of the three types of structs in Rust. The other two are classic C structs and unit structs.
Tuple structs use the struct keyword. Unlike classic ‘C structs’, the fields in a tuple struct are placed within parentheses and are not named. The tuple struct itself is named but its’ fields are anonymous, consisting of the field data type only:
struct MyStruct (type1, type2, type3)
This tuple struct has a name (MyStruct), but its’ fields are not named – they are anonymous.
In this article, we will learn the essentials of tuple structs. We’ll compare them with both tuples and classic ‘C’ structs in order to learn what makes them special. In doing so, we’ll see the strengths and weaknesses of tuple structs and gain insight into their potential applications.
What Are Tuple Structs?
Tuple structs can be a bit difficult to understand because they combine features of both tuples and structs. The easiest way to understand tuple structs is to compare them with tuples and structs.
Tuple Structs vs. Tuples
Tuples are a compound data type made of a sequence of elements. Tuples are anonymous, and their fields are also anonymous:
("Bob", 42)
A tuple can be assigned to a variable using the let keyword:
let bob = ("Bob", 42);
Tuple structs are similar to tuples, but the struct is named.
To create a tuple struct version of our tuple, we first create the tuple struct and then instantiate it:
struct Person (String, i32);
let bob = Person("Bob".to_string(), 42);
One of the most important aspects of a tuple struct is the creation of the struct itself, which is a custom data type. In the above example, the Person struct can be instantiated as many times as we would like.
Tuple Structs vs. Classic C Structs
It’s also helpful to compare tuple structs with classic C structs.
Classic structs are named and also have named fields:
struct Person {
Name: String,
Age: i32,
}
The fields of a classic struct consist of key-value pairs consisting of the field name (the key) and the data type (the value).
In contrast, the fields of a tuple struct are anonymous. Only the data type is specified:
struct Person (String, i32);
Because the fields of a tuple struct are anonymous, we can no longer access them by name. This has important implications for how tuple structs can be used in our programs.
Accessing Values From a Tuple Struct
Classic structs have named fields, which means that the values of a struct instance can be accessed using dot notation:
Classic Structs Only: my_struct.<field name>
Tuple structs don’t have field names, so this method can’t be applied to them.
Instead, we are limited to accessing values by the same methods that we can use with tuples: by index or by unpacking.
Access Tuple Struct Values By Index
As with tuples, the values in a tuple struct can be accessed by index number. This allows individual values to be accessed using dot notation:
my_struct.<index>
The value of the first field has an index of zero (0).
For example:
struct Person (String, i32);
let bob = Person("Bob".to_string(), 42);
println!("Name: {}", bob.0);
println!("Age: {}", bob.1);
Standard Output:
Name: Bob
Age: 42
Access Tuple Struct Values By Unpacking
We can also access the values of a tuple struct via unpacking. Unpacking calls all of the values in the struct at once, which can then be assigned to individual variables.
Unlike tuples, we have to include the type name of the struct or we will get a type error when unpacking:
let StructName(var1, var2) = my_struct;
This is needed because the Rust compiler will assume a tuple type instead of the custom struct type.
For example:
struct Person (String, i32);
let bob = Person("Bob".to_string(), 42);
let (name, age) = bob;
println!("Name: {}", name);
println!("Age: {}", age);
Standard Output:
Name: Bob
Age: 42