Records (Dart 3)
Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy — Lektion 86 von 110.
Dart 3 hat Records eingeführt – eine leichtgewichtige Möglichkeit, mehrere Werte zusammenzufassen, ohne eine vollständige Klasse zu erstellen. Records sind unveränderlich, verfügen über eine integrierte Gleichheitsprüfung und eignen sich perfekt dafür, mehrere Werte von einer Funktion zurückzugeben oder verwandte Daten vorübergehend zu gruppieren.
Erstellen Sie einen Record, indem Sie Werte in Klammern einschließen:
void main() {
// Ein einfacher Record mit zwei Werten
var point = (10, 20);
print(point.$1); // 10 - Zugriff auf das erste Element
print(point.$2); // 20 - Zugriff auf das zweite Element
// Records mit benannten Feldern
var person = (name: 'Alice', age: 30);
print(person.name); // Alice
print(person.age); // 30
}Auf Positionsfelder wird mit $1, $2 usw. zugegriffen, während benannte Felder ihre Namen direkt verwenden. Sie können beide Stile in einem einzelnen Datensatz mischen.
Records glänzen, wenn mehrere Werte von Funktionen zurückgegeben werden – es ist nicht nötig, eine Klasse zu erstellen, nur um zwei Datenelemente zurückzugeben:
(int, int) divideWithRemainder(int a, int b) {
return (a ~/ b, a % b);
}
(String name, int age) getUser() {
return ('Bob', 25);
}
void main() {
var (quotient, remainder) = divideWithRemainder(17, 5);
print('$quotient remainder $remainder'); // 3 Rest 2
var (name, age) = getUser();
print('$name is $age'); // Bob ist 25
}Records unterstützen automatisch die Gleichheit basierend auf ihren Werten, was sie praktisch für Vergleiche macht, ohne dass Sie == selbst implementieren müssen. Verwenden Sie Records, wenn Sie einfache, unveränderliche Datengruppierungen benötigen; verwenden Sie Klassen, wenn Sie Methoden, Veränderlichkeit oder komplexeres Verhalten benötigen.
Aufgabe
EinfachLassen Sie uns ein Koordinatensystem mit Records erstellen! Sie werden Funktionen entwickeln, die mit 2D-Punkten arbeiten, die als Records dargestellt werden. Dabei wird demonstriert, wie Records es einfach machen, mehrere zusammengehörige Werte zurückzugeben und mit ihnen zu arbeiten, ohne vollständige Klassen erstellen zu müssen.
Sie werden Ihren Code in zwei Dateien organisieren:
geometry.dart: Erstellen Sie Funktionen, die Records verwenden, um mit Koordinatendaten zu arbeiten:- Eine Funktion
createPoint(int x, int y), die einen Record mit den benannten Feldernxundyzurückgibt. Der Rückgabetyp sollte({int x, int y})sein. - Eine Funktion
midpoint(({int x, int y}) p1, ({int x, int y}) p2), die den Mittelpunkt zwischen zwei Punkten berechnet und als Record mit benannten Feldern zurückgibt. Verwenden Sie für die Berechnung die Ganzzahldivision (~/). - Eine Funktion
distance(({int x, int y}) p1, ({int x, int y}) p2), die einen Record mit positionellen Feldern zurückgibt: die horizontale Distanz (Differenz in x) und die vertikale Distanz (Differenz in y). Der Rückgabetyp sollte(int, int)sein. Berechnen Sie dies alsp2.x - p1.xundp2.y - p1.y.
- Eine Funktion
main.dart: Importieren Sie Ihre Geometrie-Datei und demonstrieren Sie Records in Aktion:- Erstellen Sie zwei Punkte mit
createPoint: Punkt A bei(2, 4)und Punkt B bei(10, 8). - Geben Sie
'Point A: (${pointA.x}, ${pointA.y})'unter Verwendung der benannten Felder aus. - Geben Sie
'Point B: (${pointB.x}, ${pointB.y})'unter Verwendung der benannten Felder aus. - Berechnen Sie den Mittelpunkt und geben Sie
'Midpoint: (${mid.x}, ${mid.y})'aus. - Berechnen Sie die Distanz und verwenden Sie Destructuring, um die Werte in die Variablen
dxunddyzu extrahieren, und geben Sie dann'Distance: dx=$dx, dy=$dy'aus.
- Erstellen Sie zwei Punkte mit
Beachten Sie, wie Records es Ihnen ermöglichen, mehrere Werte sauber zurückzugeben – benannte Felder für mehr Klarheit, wenn die Bedeutung wichtig ist, und positionelle Felder, wenn der Kontext offensichtlich ist!
Erwartete Ausgabe:
Point A: (2, 4)
Point B: (10, 8)
Midpoint: (6, 6)
Distance: dx=8, dy=4Spickzettel
Dart 3 hat Records eingeführt – eine leichtgewichtige Möglichkeit, mehrere Werte zu bündeln, ohne eine vollständige Klasse zu erstellen. Records sind unveränderlich (immutable) und eignen sich perfekt für die Rückgabe mehrerer Werte aus einer Funktion.
Erstellen Sie einen Record, indem Sie Werte in Klammern setzen:
// Einfacher Record mit positionalen Feldern
var point = (10, 20);
print(point.$1); // 10 - Zugriff auf das erste Element
print(point.$2); // 20 - Zugriff auf das zweite Element
// Records mit benannten Feldern
var person = (name: 'Alice', age: 30);
print(person.name); // Alice
print(person.age); // 30Auf positionale Felder wird mit $1, $2 usw. zugegriffen, während benannte Felder direkt über ihren Namen angesprochen werden.
Records sind ideal für die Rückgabe mehrerer Werte aus Funktionen:
// Rückgabetyp gibt die Record-Struktur an
(int, int) divideWithRemainder(int a, int b) {
return (a ~/ b, a % b);
}
// Benannte Felder im Rückgabetyp
(String name, int age) getUser() {
return ('Bob', 25);
}
// Destrukturierung von Records
var (quotient, remainder) = divideWithRemainder(17, 5);
print('$quotient remainder $remainder'); // 3 remainder 2
var (name, age) = getUser();
print('$name is $age'); // Bob is 25Record-Rückgabetypen mit benannten Feldern verwenden geschweifte Klammern:
({int x, int y}) createPoint(int x, int y) {
return (x: x, y: y);
}Records unterstützen automatisch die Gleichheitsprüfung basierend auf ihren Werten.
Probier es selbst
import 'geometry.dart';
void main() {
// TODO: Erstelle Punkt A bei (2, 4) mit createPoint
// TODO: Erstelle Punkt B bei (10, 8) mit createPoint
// TODO: Gib Punkt A mit benannten Feldern aus: Point A: ([x], [y])
// TODO: Gib Punkt B mit benannten Feldern aus: Point B: ([x], [y])
// TODO: Berechne den Mittelpunkt und gib ihn aus: Midpoint: ([x], [y])
// TODO: Berechne die Distanz und verwende Destructuring, um dx und dy zu extrahieren
// Dann gib aus: Distance: dx=[dx], dy=[dy]
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienBibliotheken & ImportsEinführung in die OOPKlassen vs. ObjekteDas this-SchlüsselwortMethodenInstanzvariablenKonstruktor-GrundlagenWiederholung – Einfacher Taschenrechner4Null-Sicherheit
Einführung in Null-SicherheitNullable vs. Non-NullableDie ? und ! OperatorenLate-Schlüsselwort & Null-SicherheitNull-aware OperatorenNull-Sicherheit in KlassenZusammenfassung – Benutzerprofil-System7Abstrakte Klassen & Interfaces
Abstrakte KlassenAbstrakte MethodenInterfaces in DartImplizite InterfacesImplementieren vs. ErweiternMehrfache InterfacesRückblick – Shape Calculator10Collections & Generics
Überblick über List, Set und MapTypsichere CollectionsGenerische KlassenGenerische MethodenGenerische ConstraintsIterable & IteratorZusammenfassung – Generische Speicherung13Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungExtension MethodsCallable ClassesSealed Classes (Dart 3)Records (Dart 3)Patterns & Matching (3.0)Enums mit Methoden16Projekt: Bibliotheksverwaltung
ProjektübersichtBuch- und Benutzerklassen2Konstruktoren in Dart
Standard-KonstruktorBenannte KonstruktorenInitialisierungslistenKonstante KonstruktorenFactory-KonstruktorenWeiterleitende KonstruktorenZusammenfassung – Shape Builder5Kapselung
Öffentliche vs. private MemberDie _ Präfix-KonventionSichtbarkeit auf Library-EbeneGetter & Setter im DetailInformation HidingRückblick – Schülerdatensätze8Mixins
Einführung in MixinsMixins erstellenMehrere Mixins verwendenDas on-Schlüsselwort in MixinsMixin vs. VererbungMixin vs. InterfaceZusammenfassung - Tiersystem11Spezielle Methoden
toString() überschreibenhashCode & == überschreibenComparable-Interfacecall()-MethodenoSuchMethod überschreibenZusammenfassung – Eigene Collection14Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterObserver-MusterStrategy-Muster3Klasseneigenschaften
Instanz- vs. statische MemberFinal & Const FelderLate-VariablenStatische Methoden & FelderGetter und SetterZusammenfassung – Bankkonto-Manager6Vererbung
Grundlagen der VererbungDas super-SchlüsselwortMethoden überschreibenDie @override-AnnotationDas final-Klassen-SchlüsselwortKonstruktoren & VererbungRückblick – Mitarbeiter-Hierarchie9Polymorphismus
Polymorphismus-GrundlagenPolymorphismus über InterfacesTypprüfung zur LaufzeitDie is & as OperatorenDas covariant SchlüsselwortZusammenfassung – Payment Processor