Ein Tupel ist eine Sammlung zur Speicherung von Werten unterschiedlicher Typen. Tupel werden mit runden Klammern () erstellt. Jedes Tupel ist ein eigenständiger Wert, seine Typangabe lautet (T1, T2, ...), wobei T1 und T2 die Typen der einzelnen Mitglieder im Tupel darstellen. Funktionen können mithilfe von Tupeln mehrere Ergebnisse zurückgeben, da ein einzelnes Tupel beliebig viele Daten aufnehmen kann.
1 Tupel als Funktionsparameter und Rückgabewert verwenden
// Tupel können sowohl als Eingabeparameter als auch als Rückgabewert einer Funktion dienen
fn reverse(pair: (i32, bool)) -> (bool, i32) {
// Mit let lassen sich Tupel-Mitglieder entpacken und an separate Variablen binden
let (int_param, bool_param) = pair;
// Neues Tupel mit vertauschter Reihenfolge zurückgeben
(bool_param, int_param)
}
fn main(){
// (12, true) ist ein vollständiges Zweielement-Tupel, übergeben als einzelner Parameter
let res = reverse((12, true));
// Mit dem Index .0 das erste Element des zurückgegebenen Tupels abrufen
println!("{}", res.0);
}Code-Sprache: JavaScript (javascript)
Kompilierungs- und Ausgaberesultat
E:\rustdemo\demo>rustc demo.rs
E:\rustdemo\demo>demo
trueCode-Sprache: JavaScript (javascript)
2 Definition eines 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);
}Code-Sprache: PHP (php)
Tuple-Struktur: Auf den Strukturnamen folgen direkt runde Klammern mit einer Typenliste; es gibt keine benannten Felder, Elemente werden nur über ihre Reihenfolge unterschieden;
Das Derive-Makro #[derive(Debug)]: Implementiert automatisch das Debug-Trait für die Struktur, sodass Debug-Informationen mit {:?} ausgegeben werden können;
Matrix(f32,f32,f32,f32) ist im Grunde ein spezielles Tupel, das vier Gleitkommazahlen umhüllt.
Bei der Ausführung erscheint eine Warnung, die ignoriert werden kann
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-Sprache: JavaScript (javascript)
3 Langes Tupel mit gemischten Typen + Wertabruf per Index
Zuerst ein Beispiel ansehen
fn main(){
// Langes Tupel mit vielen unterschiedlichen Datentypen
let long_tuple = (1u8, 2u16, 3u32, 4u64,
-1i8, -2i16, -3i32, -4i64,
0.1f32, 0.2f64,
'a', true);
// Über Tupel-Index lassen sich interne Werte extrahieren
println!("Long tuple first value: {}", long_tuple.0);
println!("Long tuple second value: {}", long_tuple.1);
}Code-Sprache: JavaScript (javascript)
Es dürfen gleichzeitig Daten verschiedener Typen gespeichert werden (vorzeichenlose Ganzzahlen, vorzeichenbehaftete Ganzzahlen, Gleitkommazahlen, Zeichen und Booleans können koexistieren) ;
Tupel-Index-Syntax: TupelVariable.Zahl, Indizes beginnen bei 0 ;
.0holt das erste Element,.1holt das zweite Element ;- und so weiter …
Ein Index darf nur ein festes Zahlenliteral sein, Variablen können nicht als Index verwendet werden.
Unten ungeordneter Teil——
2. Definition eines Tuple-Struct
// Die unten stehende Struktur ist für Übungen nach dem Unterricht gedacht
#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);
Code-Sprache: PHP (php)
Zugehörige Wissenspunkte
- Tuple-Struktur: Auf den Strukturnamen folgen runde Klammern mit einer Typenliste. Es gibt keine Feldnamen, Elemente werden nur über ihre Reihenfolge unterschieden ;
- Das Derive-Makro
#[derive(Debug)]: Implementiert automatisch dasDebug-Trait für die Struktur, damit Debug-Ausgabe mit{:?}funktioniert ; Matrix(f32,f32,f32,f32)ist im Grunde ein spezielles Tupel, das vier Gleitkommazahlen umhüllt.
Vollständiges Beispiel unten
#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);
fn main() {
// 1. Instanz erstellen
let mat = Matrix(1.0, 2.0, 3.0, 4.0);
// 2. Ausgeben (#[derive(Debug)] ist erforderlich für {:?})
println!("Matrix-Instanz: {:?}", mat);
// 3. Auf interne Elemente zugreifen: mit .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. Werte durch Entpacken abrufen
// Matrix(m0, m1, m2, m3) ist ein Entpack-Muster-Matching; m0/m1/m2/m3 sind selbst definierte temporäre Variablen, die die vier Tupel-Mitglieder der Struktur aufnehmen.
let Matrix(m0, m1, m2, m3) = mat;
println!("Entpacken:{} {} | {} {}", m0, m1, m2, m3);
// 5. Veränderbare Matrix, Elemente mit mut ändern
let mut mat_mut = Matrix(0.0, 0.0, 0.0, 0.0);
mat_mut.0 = 10.0;
mat_mut.3 = 99.0; // Werte lassen sich ändern
println!("Veränderbare Matrix: {:?}", mat_mut);
}Code-Sprache: PHP (php)
Ausgaberesultat
E:\rustdemo\demo>demo
Matrix-Instanz: Matrix(1.0, 2.0, 3.0, 4.0)
a=1, b=2, c=3, d=4
Entpacken:1 2 | 3 4
Veränderbare Matrix: Matrix(10.0, 0.0, 0.0, 99.0)
3 Langes Tupel mit gemischten Typen + Wertabruf per Index
fn main() {
// Langes Tupel mit vielen unterschiedlichen Datentypen
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.
// Über Tupel-Index lassen sich interne Werte extrahieren
println!("Long tuple first value: {}", long_tuple.0);
println!("Long tuple second value: {}", long_tuple.1);
}
Code-Sprache: JavaScript (javascript)
Ausgaberesultat
E:\rustdemo\demo>demo
Long tuple first value: 1
Long tuple second value: 2
Zusammenfassung
- Kernmerkmal von Tupeln: es dürfen gleichzeitig Daten verschiedener Typen gespeichert werden (vorzeichenlose Ganzzahlen, vorzeichenbehaftete Ganzzahlen, Gleitkommazahlen, Zeichen und Booleans können koexistieren) ;
- Tupel-Index-Syntax:
TupelVariable.Zahl, Indizes beginnen bei 0 ;.0holt das erste Element,.1holt das zweite Element ;
- Ein Index darf nur ein festes Zahlenliteral sein, Variablen können nicht als Index verwendet werden.
4 Verschachtelte Tupel
fn main() {
// Mitglieder eines Tupels können selbst Tupel sein, Verschachtelung wird unterstützt
let tuple_of_tuples = ((1u8, 2u16, 2u32), (4u64, -1i8), -2i16);
// Tupel unterstützen Debug-Ausgabe
println!("tuple of tuples: {:?}", tuple_of_tuples);
// Zwei . hintereinander zur Wertabfrage nutzen
println!("tuple of tuples: {:?}", tuple_of_tuples.0.1); // Gibt 2 aus
}
Code-Sprache: JavaScript (javascript)
Ausgabe
E:\rustdemo\demo>demo
tuple of tuples: ((1, 2, 2), (4, -1), -2)
tuple of tuples: 2
Zusammenfassung
- Mehrstufige Tupel-Verschachtelung ist erlaubt; Elemente des äußeren Tupels können Untertupel sein ;
- Tupel mit ≤12 Elementen implementieren automatisch das
Debug-Trait, mit dem Formatbezeichner{:?}lassen sich alle Inhalte direkt ausgeben.
5 Ausgabebeschränkung für zu lange Tupel (Kompilierfehler)
fn main() {
// Tupel mit mehr als 12 Elementen können nicht direkt mit Debug ausgegeben werden
let too_long_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
println!("Too long tuple: {:?}", too_long_tuple);
// Tipp: Kommentiere die beiden Zeilen oben aus, um den Kompilierfehler zu sehen
}
Code-Sprache: JavaScript (javascript)
Kompilierfehler
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-Sprache: PHP (php)
Zusammenfassung
Die Rust-Standardbibliothek generiert das Debug-Trait automatisch nur für Tupel mit 0 bis 12 Elementen ;
Tupel mit mehr als 12 Elementen haben keine eingebaute Debug-Implementierung, eine direkte Ausgabe mit {:?} führt zu einem Kompilierabbruch.
Löschen Sie die Zahl 13 oben und testen Sie erneut, um zu prüfen, ob der Fehler verschwindet
6 Funktionsaufruf mit Tupelparameter, vertauschtes Ergebnis beobachten
// Tupel können sowohl als Eingabeparameter als auch als Rückgabewert einer Funktion dienen
fn reverse(pair: (i32, bool)) -> (bool, i32) {
// Mit let lassen sich Tupel-Mitglieder entpacken und an separate Variablen binden
let (int_param, bool_param) = pair;
// Neues Tupel mit vertauschter Reihenfolge zurückgeben
(bool_param, int_param)
}
fn main() {
let pair = (1, true);
println!("Pair is {:?}", pair);
println!("The reversed pair is {:?}", reverse(pair)); // Oben definierte reverse-Funktion zum Vertauschen aufrufen
}Code-Sprache: JavaScript (javascript)
Ausgaberesultat
E:\rustdemo\demo>demo
Pair is (1, true)
The reversed pair is (true, 1)Code-Sprache: JavaScript (javascript)
Zusammenfassung
- Ein normales Zweielement-Tupel kann direkt als Argument an eine Funktion übergeben werden, die ein Tupel akzeptiert ;
- Die Funktion gibt ein komplett neues Tupel zurück, das ursprüngliche Tupel
pairwird nicht verändert.
7 Spezialregel mit Komma für Einzelelement-Tupel (häufige Fehlerquelle)
fn main() {
// Bei Einzelelement-Tupeln ist ein Komma zwingend erforderlich, um es von einem einfachen eingeklammerten Literal abzugrenzen
println!("One element tuple: {:?}", (5u32,));
println!("Just an integer: {:?}", (5u32));
}Code-Sprache: JavaScript (javascript)
Zusammenfassung
(5u32,): Komma am Ende, gültiges Einzelelement-Tupel mit Typ(u32,);(5u32): kein Komma, entspricht nur der normalen Zahl5u32in Klammern, kein Tupel ;- Das Komma ist das einzige Unterscheidungsmerkmal zwischen Einzelelement-Tupel und eingeklammerter Ausdruck.
8 Vollständiges Entpacken von Mehrerelement-Tupeln (siehe oben)
// Ein Tupel kann vollständig entpackt werden, um mehrere Variablen auf einmal zu binden
let tuple = (1, "hello", 4.5, true);
let (a, b, c, d) = tuple;
println!("{:?}, {:?}, {:?}, {:?}", a, b, c, d);
Code-Sprache: JavaScript (javascript)
Zusammenfassung
- Tupel beliebiger Länge lassen sich komplett entpacken; die Anzahl der Variablen links muss exakt mit der Anzahl der Tupel-Elemente übereinstimmen ;
- Nach dem Entpacken entspricht jede Variable dem Wert an derselben Position im Tupel und kann einzeln verwendet werden.
9 Instanziierung eines Tuple-Struct und Debug-Ausgabe
#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);
fn main() {
let matrix = Matrix(1.1, 1.2, 2.1, 2.2);
println!("{:?}", matrix);
}Code-Sprache: PHP (php)