A tuple is a collection that stores values of multiple distinct types. Tuples are created using parentheses (). Every tuple itself is a standalone value, with its type notation written as (T1, T2, ...), where T1 and T2 represent the type of each member inside the tuple. Functions can return multiple outputs with tuples, as a single tuple can hold any number of data entries.
1 Tuples as Function Parameters and Return Values
// Tuples can be used both as function inputs and return values
fn reverse(pair: (i32, bool)) -> (bool, i32) {
// let can destructure tuple members and bind them to separate variables
let (int_param, bool_param) = pair;
// Return a new tuple with swapped order
(bool_param, int_param)
}
fn main(){
// (12, true) is a complete two-element tuple, passed as one single argument
let res = reverse((12, true));
// Use .0 index to fetch the first element of the returned tuple
println!("{}", res.0);
}Code language: JavaScript (javascript)
Compilation and execution output
E:\rustdemo\demo>rustc demo.rs
E:\rustdemo\demo>demo
trueCode language: JavaScript (javascript)
2 Tuple Struct Definition
#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);
fn main(){
let matrix = Matrix(1.1, 1.2, 2.1, 2.2);
println!("{:?}", matrix);
}Code language: PHP (php)
Tuple structs: The struct name is followed directly by parentheses containing a list of types. There are no named fields, elements are only distinguished by their order;
The derive macro #[derive(Debug)]: Automatically implements the Debug trait for the struct, enabling debug print output with {:?};
Matrix(f32,f32,f32,f32) is essentially a special tuple wrapping four floating-point numbers.
A warning will appear during execution, which can be safely ignored
E:\rustdemo\demo>rustc demo.rs
warning: fields `0`, `1`, `2`, and `3` are never read
--> demo.rs:2:15
|
2 | struct Matrix(f32, f32, f32, f32);
| ------ ^^^ ^^^ ^^^ ^^^
| |
| fields in this struct
|
= help: consider removing these fields
= note: `Matrix` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
= note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default
warning: 1 warning emitted
E:\rustdemo\demo>demo
Matrix(1.1, 1.2, 2.1, 2.2)Code language: JavaScript (javascript)
3 Long Mixed-Type Tuples + Value Access via Indexes
Take a look at the example below
fn main(){
// A long tuple containing multiple different data types
let long_tuple = (1u8, 2u16, 3u32, 4u64,
-1i8, -2i16, -3i32, -4i64,
0.1f32, 0.2f64,
'a', true);
// Internal values can be retrieved using tuple indexes
println!("Long tuple first value: {}", long_tuple.0);
println!("Long tuple second value: {}", long_tuple.1);
}Code language: JavaScript (javascript)
Supports storing different data types simultaneously (unsigned integers, signed integers, floats, characters and booleans can coexist);
Tuple index syntax: tuple_variable.number, indexes start from 0;
.0accesses the first element,.1accesses the second element;- and so on….
Indexes can only be fixed numeric literals; variables cannot be used as indexes.
Unorganized content below——
2. Tuple Struct Definition
// The struct below is for after-class exercises
#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);
Code language: PHP (php)
Related Knowledge Points
- Tuple struct: The struct name is followed by parentheses with a list of types inside. There are no field names, elements are distinguished only by order;
- The derive macro
#[derive(Debug)]: Automatically implements theDebugtrait for the struct, allowing debug printing with{:?}; Matrix(f32,f32,f32,f32)is essentially a special tuple wrapping four floating-point numbers.
Full example below
#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);
fn main() {
// 1. Create an instance
let mat = Matrix(1.0, 2.0, 3.0, 4.0);
// 2. Print (#[derive(Debug)] is required to use {:?})
println!("Matrix instance: {:?}", mat);
// 3. Access internal elements via .index
let a = mat.0;
let b = mat.1;
let c = mat.2;
let d = mat.3;
println!("a={}, b={}, c={}, d={}", a, b, c, d);
// 4. Destructuring to get values
// Matrix(m0, m1, m2, m3) is a destructuring pattern match. m0/m1/m2/m3 are custom temporary variables to store the four tuple members inside the struct.
let Matrix(m0, m1, m2, m3) = mat;
println!("Destructure: {} {} | {} {}", m0, m1, m2, m3);
// 5. Mutable matrix, modify elements with mut keyword
let mut mat_mut = Matrix(0.0, 0.0, 0.0, 0.0);
mat_mut.0 = 10.0;
mat_mut.3 = 99.0; // Values can be modified
println!("Mutable matrix: {:?}", mat_mut);
}Code language: PHP (php)
Execution output
E:\rustdemo\demo>demo
Matrix instance: Matrix(1.0, 2.0, 3.0, 4.0)
a=1, b=2, c=3, d=4
Destructure: 1 2 | 3 4
Mutable matrix: Matrix(10.0, 0.0, 0.0, 99.0)
3. Long Mixed-Type Tuples + Value Access via Indexes
fn main() {
// A long tuple containing multiple different data types
let long_tuple = (1u8, 2u16, 3u32, 4u64,
-1i8, -2i16, -3i32, -4i64,
0.1f32, 0.2f64,
'a', true);
// Values can be extracted from the tuple using tuple indexing.
println!("Long tuple first value: {}", long_tuple.0);
println!("Long tuple second value: {}", long_tuple.1);
}
Code language: JavaScript (javascript)
Execution output
E:\rustdemo\demo>demo
Long tuple first value: 1
Long tuple second value: 2
Summary
- Core feature of tuples: supports storing different data types simultaneously (unsigned integers, signed integers, floats, characters and booleans can coexist);
- Tuple index syntax:
tuple_variable.number, indexes start from 0;.0accesses the first element,.1accesses the second element;
- Indexes can only be fixed numeric literals; variables cannot be used as indexes.
4. Nested Tuples
fn main() {
// Tuple members can themselves be tuples; nesting is supported
let tuple_of_tuples = ((1u8, 2u16, 2u32), (4u64, -1i8), -2i16);
// Tuples support debug printing
println!("tuple of tuples: {:?}", tuple_of_tuples);
// Chain two . accessors to fetch nested values
println!("tuple of tuples: {:?}", tuple_of_tuples.0.1); // Outputs 2
}
Code language: JavaScript (javascript)
Output
E:\rustdemo\demo>demo
tuple of tuples: ((1, 2, 2), (4, -1), -2)
tuple of tuples: 2
Summary
- Multi-level tuple nesting is supported; elements of outer tuples can be child tuples;
- Tuples with ≤12 elements automatically implement the
Debugtrait; the format specifier{:?}can print all contents directly.
5. Print Restriction for Over-Long Tuples (Compile Error)
fn main() {
// Tuples with more than 12 elements cannot be printed directly with Debug
let too_long_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
println!("Too long tuple: {:?}", too_long_tuple);
// Tip: Uncomment the two lines above to view the compiler error
}
Code language: JavaScript (javascript)
Compile error log
E:\rustdemo\demo>rustc demo.rs
error[E0277]: `({integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer})` doesn't implement `Debug`
--> demo.rs:5:38
|
5 | println!("Too long tuple: {:?}", too_long_tuple);
| ---- ^^^^^^^^^^^^^^ `({integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer})` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| |
| required by this formatting parameter
|
= help: the trait `Debug` is not implemented for `({integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer})`
= help: the following other types implement trait `Debug`:
()
(A, Z, Y, X, W, V, U, T)
(B, A, Z, Y, X, W, V, U, T)
(C, B, A, Z, Y, X, W, V, U, T)
(D, C, B, A, Z, Y, X, W, V, U, T)
(E, D, C, B, A, Z, Y, X, W, V, U, T)
(T,)
(U, T)
and 5 others
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.Code language: PHP (php)
Summary
The Rust standard library only auto-derives the Debug trait for tuples with 0~12 elements;
Tuples with more than 12 elements have no built-in Debug implementation, and direct printing with {:?} will fail compilation.
You can delete the number 13 above and test it to see if the error disappears
6. Call Functions With Tuple Parameters & Observe Swapped Output
// Tuples can be used both as function inputs and return values
fn reverse(pair: (i32, bool)) -> (bool, i32) {
// let can destructure tuple members and bind them to separate variables
let (int_param, bool_param) = pair;
// Return a new tuple with swapped order
(bool_param, int_param)
}
fn main() {
let pair = (1, true);
println!("Pair is {:?}", pair);
println!("The reversed pair is {:?}", reverse(pair)); // Call reverse to swap elements
}Code language: JavaScript (javascript)
Execution output
E:\rustdemo\demo>demo
Pair is (1, true)
The reversed pair is (true, 1)Code language: JavaScript (javascript)
Summary
- Standard two-element tuples can be passed directly as arguments to functions accepting tuple inputs;
- The function returns a brand new tuple; the original
pairtuple remains unmodified.
7. Special Comma Rule for Single-Element Tuples (Common Pitfall)
fn main() {
// A trailing comma is mandatory when creating single-element tuples, to distinguish them from regular literals wrapped only in parentheses
println!("One element tuple: {:?}", (5u32,));
println!("Just an integer: {:?}", (5u32));
}Code language: PHP (php)
Summary
(5u32,): Trailing comma present, this is a valid single-element tuple with type(u32,);(5u32): No comma, this is just equivalent to the regular number5u32wrapped in parentheses, not a tuple;- The comma is the only marker to tell single-element tuples apart from parenthesized expressions.
8. Full Destructuring of Multi-Element Tuples (Reference Above)
// Tuples can be fully destructured to bind multiple variables at once
let tuple = (1, "hello", 4.5, true);
let (a, b, c, d) = tuple;
println!("{:?}, {:?}, {:?}, {:?}", a, b, c, d);
Code language: JavaScript (javascript)
Summary
- Tuples of any length support full destructuring; the number of variables on the left must exactly match the number of tuple elements;
- After destructuring, each variable holds the value from its matching position in the tuple and can be used independently.
9. Tuple Struct Instantiation & Debug Printing
#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);
fn main() {
let matrix = Matrix(1.1, 1.2, 2.1, 2.2);
println!("{:?}", matrix);
}Code language: PHP (php)
Summary
- Tuple struct instantiation syntax:
StructName(value1, value2, ...); - With
#[derive(Debug)]added, the struct supports debug printing via{:?}.