Un tuple est une collection destinée à stocker plusieurs valeurs de types différents. Les tuples se créent à l’aide de parenthèses (). Chaque tuple est lui-même une valeur indépendante, son type s’écrit sous la forme (T1, T2, ...), où T1 et T2 correspondent aux types de chaque membre du tuple. Les fonctions peuvent renvoyer plusieurs résultats grâce aux tuples, car un seul tuple peut contenir un nombre quelconque de données.
1 Utiliser un tuple comme paramètre et valeur de retour de fonction
// Les tuples peuvent servir à la fois de paramètres d'entrée et de valeurs de retour d'une fonction
fn reverse(pair: (i32, bool)) -> (bool, i32) {
// L'instruction let permet de déstructurer les membres d'un tuple et de les lier à des variables distinctes
let (int_param, bool_param) = pair;
// Retourner un nouveau tuple dont l'ordre des éléments est inversé
(bool_param, int_param)
}
fn main(){
// (12, true) est un tuple à deux éléments complet, transmis en tant qu'un unique paramètre
let res = reverse((12, true));
// Utiliser l'index .0 pour récupérer le premier élément du tuple renvoyé
println!("{}", res.0);
}Langage du code : JavaScript (javascript)
Résultat de la compilation et de l’exécution
E:\rustdemo\demo>rustc demo.rs
E:\rustdemo\demo>demo
trueLangage du code : JavaScript (javascript)
2 Définition d’un tuple struct
#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);
fn main(){
let matrix = Matrix(1.1, 1.2, 2.1, 2.2);
println!("{:?}", matrix);
}Langage du code : PHP (php)
Tuple struct : le nom de la structure est suivi directement de parenthèses contenant une liste de types, sans champs nommés ; les éléments ne se distinguent que par leur ordre ;
La macro dérivée #[derive(Debug)] : implémente automatiquement le trait Debug pour la structure, ce qui permet d’afficher des informations de débogage avec {:?} ;
Matrix(f32,f32,f32,f32) est en réalité un tuple spécial qui encapsule quatre nombres à virgule flottante.
Un avertissement s’affichera lors de l’exécution, vous pouvez l’ignorer sans risque
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)Langage du code : JavaScript (javascript)
3 Long tuple à types mixtes + récupération des valeurs par index
Voyons d’abord un exemple
fn main(){
// Long tuple contenant plusieurs types de données différents
let long_tuple = (1u8, 2u16, 3u32, 4u64,
-1i8, -2i16, -3i32, -4i64,
0.1f32, 0.2f64,
'a', true);
// On peut extraire les valeurs internes à l'aide des index du tuple
println!("Long tuple first value: {}", long_tuple.0);
println!("Long tuple second value: {}", long_tuple.1);
}Langage du code : JavaScript (javascript)
Autorise le stockage simultané de données de types variés (entiers non signés, entiers signés, nombres à virgule flottante, caractères et booléens peuvent coexister) ;
Syntaxe des index de tuple : variable_tuple.chiffre, les index commencent à 0 ;
.0permet d’accéder au premier élément,.1permet d’accéder au second élément ;- et ainsi de suite…
L’index ne peut être qu’un littéral numérique fixe, il est impossible d’utiliser une variable comme index.
Partie non triée ci-dessous——
2. Définition d’un tuple struct
// La structure ci-dessous est destinée aux exercices après le cours
#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);
Langage du code : PHP (php)
Points de connaissance associés
- Tuple struct : le nom de la structure est suivi de parenthèses contenant une liste de types. Il n’y a pas de noms de champs, les éléments se distinguent uniquement par leur ordre ;
- La macro dérivée
#[derive(Debug)]: implémente automatiquement le traitDebugpour la structure, permettant l’affichage de débogage avec{:?}; Matrix(f32,f32,f32,f32)est en réalité un tuple spécial qui encapsule quatre nombres à virgule flottante.
Exemple complet ci-dessous
#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);
fn main() {
// 1. Créer une instance
let mat = Matrix(1.0, 2.0, 3.0, 4.0);
// 2. Afficher (il faut #[derive(Debug)] pour utiliser {:?})
println!("Instance de matrice: {:?}", mat);
// 3. Accéder aux éléments internes 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. Récupérer les valeurs par déstructuration
// Matrix(m0, m1, m2, m3) est un motif de déstructuration ; m0/m1/m2/m3 sont des variables temporaires personnalisées qui reçoivent les quatre membres du tuple de la structure.
let Matrix(m0, m1, m2, m3) = mat;
println!("Déstructuration : {} {} | {} {}", m0, m1, m2, m3);
// 5. Matrice mutable, modifier les éléments avec mut
let mut mat_mut = Matrix(0.0, 0.0, 0.0, 0.0);
mat_mut.0 = 10.0;
mat_mut.3 = 99.0; // Les valeurs sont modifiables
println!("Matrice mutable: {:?}", mat_mut);
}Langage du code : PHP (php)
Résultat de l’exécution
E:\rustdemo\demo>demo
Instance de matrice: Matrix(1.0, 2.0, 3.0, 4.0)
a=1, b=2, c=3, d=4
Déstructuration : 1 2 | 3 4
Matrice mutable: Matrix(10.0, 0.0, 0.0, 99.0)
3 Long tuple à types mixtes + récupération des valeurs par index
fn main() {
// Long tuple contenant plusieurs types de données différents
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.
// On peut extraire les valeurs internes à l'aide des index du tuple
println!("Long tuple first value: {}", long_tuple.0);
println!("Long tuple second value: {}", long_tuple.1);
}
Langage du code : JavaScript (javascript)
Résultat de l’exécution
E:\rustdemo\demo>demo
Long tuple first value: 1
Long tuple second value: 2
Synthèse
- Caractéristique principale des tuples : autorise le stockage simultané de données de types variés (entiers non signés, entiers signés, nombres à virgule flottante, caractères et booléens peuvent coexister) ;
- Syntaxe des index de tuple :
variable_tuple.chiffre, les index commencent à 0 ;.0permet d’accéder au premier élément,.1permet d’accéder au second élément ;
- L’index ne peut être qu’un littéral numérique fixe, il est impossible d’utiliser une variable comme index.
4 Tuples imbriqués
fn main() {
// Les membres d'un tuple peuvent eux-mêmes être des tuples, l'imbrication est prise en charge
let tuple_of_tuples = ((1u8, 2u16, 2u32), (4u64, -1i8), -2i16);
// Les tuples prennent en charge l'affichage de débogage
println!("tuple of tuples: {:?}", tuple_of_tuples);
// Utiliser deux points consécutifs pour accéder aux valeurs imbriquées
println!("tuple of tuples: {:?}", tuple_of_tuples.0.1); // Affiche 2
}
Langage du code : JavaScript (javascript)
Sortie
E:\rustdemo\demo>demo
tuple of tuples: ((1, 2, 2), (4, -1), -2)
tuple of tuples: 2
Synthèse
- L’imbrication à plusieurs niveaux de tuples est prise en charge ; les éléments d’un tuple externe peuvent être des sous-tuples ;
- Les tuples avec ≤12 éléments implémentent automatiquement le trait
Debug; le spécificateur de format{:?}permet d’afficher directement tout le contenu.
5 Limitation d’affichage des tuples trop longs (erreur de compilation)
fn main() {
// Mais les tuples avec plus de 12 éléments ne peuvent pas être affichés directement avec 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);
// Astuce : décommentez les deux lignes ci-dessus pour voir l'erreur du compilateur
}
Langage du code : JavaScript (javascript)
Erreur de compilation
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`.Langage du code : PHP (php)
Synthèse
La bibliothèque standard Rust ne dérive automatiquement le trait Debug que pour les tuples contenant 0 à 12 éléments ;
Les tuples avec plus de 12 éléments n’ont pas d’implémentation native de Debug ; un affichage direct avec {:?} provoque un échec de compilation.
Vous pouvez supprimer le nombre 13 ci-dessus et tester pour vérifier que l’erreur disparaît
6 Appel de fonction avec paramètre tuple, observer le résultat inversé
// Les tuples peuvent servir à la fois de paramètres d'entrée et de valeurs de retour d'une fonction
fn reverse(pair: (i32, bool)) -> (bool, i32) {
// L'instruction let permet de déstructurer les membres d'un tuple et de les lier à des variables distinctes
let (int_param, bool_param) = pair;
// Retourner un nouveau tuple dont l'ordre des éléments est inversé
(bool_param, int_param)
}
fn main() {
let pair = (1, true);
println!("Pair is {:?}", pair);
println!("The reversed pair is {:?}", reverse(pair)); // Appeler reverse pour inverser l'ordre
}Langage du code : JavaScript (javascript)
Résultat de l’exécution
E:\rustdemo\demo>demo
Pair is (1, true)
The reversed pair is (true, 1)Langage du code : JavaScript (javascript)
Synthèse
- Un tuple à deux éléments classique peut être passé directement en argument à une fonction qui accepte un tuple ;
- La fonction renvoie un tout nouveau tuple ; le tuple initial
pairn’est pas modifié.
7 Règle spéciale de la virgule pour les tuples à un seul élément (point d’erreur fréquent)
fn main() {
// Il faut obligatoirement ajouter une virgule lors de la création d'un tuple à un seul élément, pour le distinguer d'un littéral simple juste entre parenthèses
println!("One element tuple: {:?}", (5u32,));
println!("Just an integer: {:?}", (5u32));
}Langage du code : JavaScript (javascript)
Synthèse
(5u32,): virgule en fin de ligne, c’est un tuple valide à un seul élément, de type(u32,);(5u32): pas de virgule, équivaut simplement au nombre classique5u32encadré par des parenthèses, ce n’est pas un tuple ;- La virgule est le seul marqueur qui permet de distinguer un tuple à un seul élément d’une expression entre parenthèses.
8 Déstructuration complète de tuples multi-éléments (voir ci-dessus)
// Un tuple peut être complètement déstructuré pour lier plusieurs variables en une seule fois
let tuple = (1, "hello", 4.5, true);
let (a, b, c, d) = tuple;
println!("{:?}, {:?}, {:?}, {:?}", a, b, c, d);
Langage du code : JavaScript (javascript)
Synthèse
- Tout tuple, quelle que soit sa longueur, peut être déstructuré globalement ; le nombre de variables à gauche doit correspondre exactement au nombre d’éléments du tuple ;
- Après déstructuration, chaque variable correspond indépendamment à la valeur de la position correspondante du tuple et peut être utilisée seule.
9 Instanciation d’un tuple struct et affichage Debug
#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);
fn main() {
let matrix = Matrix(1.1, 1.2, 2.1, 2.2);
println!("{:?}", matrix);
}Langage du code : PHP (php)
Synthèse
- Syntaxe d’instanciation d’un tuple struct :
NomStructure(valeur1, valeur2, ...); - Avec l’ajout de
#[derive(Debug)], la structure prend en charge l’affichage de débogage via{:?}.