Day 8: Tuples
Hello again, Rustaceans! 🦀
Today, we’re going to learn about tuples in Rust. Tuples are a simple yet powerful feature that allows us to group together multiple values of different types. They are useful when you want to return multiple values from a function or when you want to group related data together.
let my_tuple: (i32, f64, String) = (10, 3.14, "Hello".to_string());
Here, my_tuple
is a tuple that holds an integer, a floating-point number, and a string. Notice how we can store different types of data in the same tuple - that’s one of the things that make tuples so versatile!
Accessing elements in a tuple is straightforward. We use the dot operator followed by the index of the element:
println!("First element (integer): {}", my_tuple.0);
println!("Second element (float): {}", my_tuple.1);
println!("Third element (string): {}", my_tuple.2);
But what if we want to assign the values of a tuple to separate variables? That’s where destructuring comes in:
let (x, y, z) = my_tuple;
println!("Destructured values: x = {}, y = {}, z = {}", x, y, z);
With destructuring, we can assign the values of the tuple to the variables x
, y
, and z
in a single line of code. Neat, right?
If you’ve used Python, you might have come across functions that return more than one value. For instance, consider a function that calculates the area and circumference of a circle:
import math
def circle_properties(radius):
area = math.pi * radius ** 2
circumference = 2 * math.pi * radius
return area, circumference
area, circumference = circle_properties(5)
print(f"Area: {area}, Circumference: {circumference}")
In this Python code, circle_properties
return two values, which are then assigned to area
and circumference
respectively.
As I’ve said in the past, Rust is like a hybrid of C and Python. It takes all the good things from Python, such as returning multiple values from a function, while maintaining the low memory usage and zero-cost abstractions of C/C++. You can use tuples in Rust to achieve results similar to Python.
Consider a function in Rust that calculates the area and circumference of a circle:
fn circle_properties(radius: f64) -> (f64, f64) {
let area = std::f64::consts::PI * radius.powi(2);
let circumference = 2.0 * std::f64::consts::PI * radius;
(area, circumference)
}
In this function, we’re calculating the area (std::f64::consts::PI * radius.powi(2)
) and the circumference (2.0 * std::f64::consts::PI * radius
) of a circle. We then return these two values as a tuple.
Now, how do we use this function and access its return values? That’s where destructuring comes in handy:
fn main() {
let (area, circumference) = circle_properties(5.0);
println!("Area: {}, Circumference: {}", area, circumference);
}
Here, we’re calling circle_properties
with a radius of 5.0
. The function returns a tuple, which we immediately destructure into the variables area
and circumference
. We can then use these variables as we please.
In Rust, once a tuple is created, its size and the types of its elements cannot be changed. This might give the impression that tuples are immutable, but that's not true. Elements of a tuple can be mutated.
// Tuple elements can be mutated:
let mut another_tuple = (1, vec![2, 3, 4]);
another_tuple.1.push(5); // Modifying the vector within the tuple
println!("Modified tuple: {:?}", another_tuple);
Today, we looked into how to use tuples in Rust. We explored how to create tuples, access their elements, destructure them, and even mutate their elements. We also saw how tuples can be used to return multiple values from a function, a powerful feature that allows for cleaner, more expressive code.
Understanding these aspects of tuples is crucial when it comes to writing efficient, readable, and maintainable Rust code. As always, the journey of learning never ends, and there’s always more to explore in the vast world of Rust.
You can find all the code examples from today’s session on the inpyjama GitHub page: https://github.com/inpyjama/rust/tree/main/day8
See you tomorrow !!
Discussion