Dart Enums und Symbole
Ein Enum wird verwendet, um eine Menge benannter konstanter Werte zu definieren, wodurch der Code lesbarer wird.
Dieses Kapitel führt in die Definition von Dart-Enums, erweiterten Enums (mit Methoden und Eigenschaften) sowie die Typen Symbol und Rune ein.
enum Enum-Definition
Ein Enum ist eine spezielle Art von Klasse, die verwendet wird, um eine feste Anzahl konstanter Werte darzustellen.
Die typischsten Szenarien sind die Darstellung endlicher Optionen wie Zustände, Richtungen, Farben usw.
Beispiel
enum Status {
pending, // Ausstehend
approved, // Genehmigt
rejected, // Abgelehnt
cancelled, // Storniert
}
void main() {
// Enum-Werte verwenden
Status currentStatus = Status.pending;
print('Aktueller Status: $currentStatus');
// Den Index über .index abrufen (beginnend bei 0)
print('Indexwert: ${currentStatus.index}'); // 0
// Alle Enum-Werte über .values abrufen
print(Alle Status: ${Status.values});
// Alle Enum-Werte durchlaufen
for (var status in Status.values) {
print(BEISPIEL Status: $status, Index: ${status.index});
}
// Enum-Wert per String abrufen
Status parsed = Status.values.byName('approved');
print(Geparster Status: $parsed);
// Enums in switch verwenden
switch (currentStatus) {
case Status.pending:
print(Bestellung ausstehend);
break;
case Status.approved:
print(Bestellung genehmigt);
break;
case Status.rejected:
print(Bestellung abgelehnt);
break;
case Status.cancelled:
print(Bestellung storniert);
break;
}
}
当前状态: Status.pending 索引值: 0 所有状态: [Status.pending, Status.approved, Status.rejected, Status.cancelled] EXAMPLE 状态: Status.pending, 索引: 0 EXAMPLE 状态: Status.approved, 索引: 1 EXAMPLE 状态: Status.rejected, 索引: 2 EXAMPLE 状态: Status.cancelled, 索引: 3 解析出的状态: Status.approved 订单待处理
Enums und switch sind ein perfektes Paar. Wenn du alle Enum-Werte in einem switch behandelst, prüft der Dart-Compiler, ob du alle Fälle abgedeckt hast. Das vermeidet Fehler durch fehlende Zweige.
Erweiterte Enums (mit Methoden und Eigenschaften)
Dart 3.0 führte erweiterte Enums ein, die es Enums ermöglichen, Felder, Methoden und Konstruktoren zu haben.
Beispiel
enum HttpStatus {
// Enum-Werte übergeben Parameter über den Konstruktor
ok(200, Anfrage erfolgreich),
created(201, Ressource erstellt),
badRequest(400, Ungültige Anfrage),
unauthorized(401, Nicht autorisiert),
notFound(404, Ressource nicht gefunden),
serverError(500, Interner Serverfehler);
// Mitgliedsvariablen: Jeder enum-Wert hat code und message
final int code;
final String message;
// Konstruktor: muss const sein
const HttpStatus(this.code, this.message);
// Enum-Methode
bool get isSuccess => code >= 200 && code < 300;
bool get isClientError => code >= 400 && code < 500;
bool get isServerError => code >= 500;
// Statische Methode: Enum anhand des Statuscodes finden
static HttpStatus? fromCode(int code) {
try {
return HttpStatus.values.firstWhere((s) => s.code == code);
} catch (_) {
return null;
}
}
}
void main() {
var status = HttpStatus.notFound;
print(BEISPIEL HTTP-Status: $status);
print(Statuscode: ${status.code});
print(Meldung: ${status.message});
print(Ist erfolgreich: ${status.isSuccess});
print('Ist Client-Fehler: ${status.isClientError}');
// Nachschlagen mit einer statischen Methode
var found = HttpStatus.fromCode(201);
if (found != null) {
print('Gefundener Status: ${found.message}');
}
var unknown = HttpStatus.fromCode(999);
print('Unbekannter Statuscode: $unknown');
}
EXAMPLE HTTP 状态: HttpStatus.notFound 状态码: 404 Message: 资源未找到 是否成功: false 是否客户端错误: true 找到状态: 资源已创建 未知状态码: null
Erweiterte Enums erheben Enums von "Sammlungen benannter Konstanten" zu "Typen mit Verhalten", wodurch sie Logik im Zusammenhang mit dem Enum kapseln können.
Die Konstruktoren erweiterter Enums müssen const sein, und Membervariablen müssen final sein. Das liegt daran, dass Enum-Werte selbst Kompilierzeitkonstanten sind.
Symbol-Typ
Symbol repräsentiert Bezeichner in Dart-Programmen (Variablennamen, Funktionsnamen usw.).
Es wird im täglichen Entwicklungsalltag nicht häufig verwendet; es wird hauptsächlich in Reflexions- und Codegenerierungsszenarien eingesetzt.
Beispiel
// Verwende das Präfix #, um ein Symbol zu erstellen
Symbol sym1 = #example;
Symbol sym2 = #helloWorld;
print('Symbol 1: $sym1'); // Symbol("example")
print('Symbol 2: $sym2'); // Symbol("helloWorld")
// Symbol-Vergleich
Symbol sym3 = #example;
print('sym1 == sym3: ${sym1 == sym3}'); // true
// Symbol kann als Map-Schlüssel verwendet werden
var metadata = {
#author: 'EXAMPLE',
#version: '1.0.0',
#description: Dart-Tutorial,
};
print('Autor: ${metadata[#author]}');
}
Symbol 1: Symbol("example")
Symbol 2: Symbol("helloWorld")
sym1 == sym3: true
作者: EXAMPLE
Symbole werden nach der Dart-Kompilierung normalerweise minifiziert, daher sollte man sich für logische Entscheidungen nicht auf das Ergebnis von Symbol("example").toString() verlassen. Die korrekte Verwendung von Symbol dient Reflexionsoperationen über die Bibliothek dart:mirrors.
Runes und Unicode
Rune ist der Typ in Dart, der Unicode-Codepunkte repräsentiert.
In Dart sind Strings in UTF-16 kodierte Sequenzen.
Für Zeichen außerhalb der Basic Multilingual Plane (BMP), wie z. B. Emojis, wird Rune benötigt, um sie zu verarbeiten.
Beispiel
// Die Unicode-Codepunkte des Strings abrufen
String text = 'EXAMPLE';
print('Character: $text');
print('Code point list: ${text.runes.toList()}');
// Über jedes Zeichen und seinen Codepunkt iterieren
for (var char in text.runes) {
print('${String.fromCharCode(char)} -> U+${char.toRadixString(16).toUpperCase().padLeft(4, '0')}');
}
// Ein Zeichen aus einem Codepunkt erstellen
var heart = String.fromCharCode(0x2764);
print('Herz: $heart');
// Mehrfach-Codepunkt-Zeichen behandeln (wie einige Emojis)
var smile = '\u{1F600}'; // Verwende die \u{}-Syntax, um Zeichen außerhalb der BMP darzustellen
print('Smiley: $smile');
// Die Codepunkte eines Zeichens mit mehreren Codepunkten abrufen
print('Smiley-Codepunkte: ${smile.runes.map((r) => 'U+${r.toRadixString(16).toUpperCase()}').toList()}');
}
字符: EXAMPLE 码点列表: [82, 85, 78, 79, 79, 66] R -> U+0052 U -> U+0055 N -> U+004E O -> U+004F O -> U+004F B -> U+0042 心形: ❤ 笑脸: 😀 笑脸码点: [U+1F600]
In der alltäglichen Entwicklung müssen Sie nicht direkt mit Rune arbeiten; Strings selbst kommen gut mit Unicode zurecht.
Rune wird hauptsächlich verwendet, wenn eine präzise Manipulation von Zeichen-Codepunkten erforderlich ist, z. B. in Low-Level-Szenarien wie Texteditoren und Schriftrendering.
Weitere Erweiterungen