Dart-Kontrollfluss

Der Kontrollfluss bestimmt die Reihenfolge, in der Code in einem Programm ausgeführt wird.

Dieses Kapitel führt in bedingte Anweisungen (if/else, switch) und Schleifenanweisungen (for, while) in Dart ein sowie in die Verwendung von break und continue.


if / else / else if – Bedingte Anweisungen

Die if-Anweisung ist die grundlegendste Kontrollflussstruktur; sie entscheidet anhand einer Bedingung, ob ein Codeabschnitt ausgeführt wird.

Beispiel

Grundlegende if-Anweisungen:

void main() {
  int score = 85;

  // Grundlegendes if: wird ausgeführt, wenn die Bedingung wahr ist
  if (score >= 60) {
    print(EXAMPLE, herzlichen Glückwunsch, du hast bestanden!);
  }

  // if-else: wähle eines von zwei
  if (score >= 90) {
    print('Ausgezeichnet');
  } else {
    print(Weiter so!);
  }

  // if-else if-else: Auswahl mit mehreren Zweigen
  if (score >= 90) {
    print(Note: A);
  } else if (score >= 80) {
    print(Note: B);
  } else if (score >= 70) {
    print(Note: C);
  } else if (score >= 60) {
    print(Note: D);
  } else {
    print(Note: F (nicht bestanden));
  }
}
EXAMPLE 恭喜,你及格了!
继续加油
等级:B

In Dart müssen Bedingungsausdrücke vom Typ bool sein. Du kannst 0, '', null usw. nicht wie in JavaScript als Bedingungen verwenden – diese führen in Dart direkt zu Kompilierungsfehlern.

Verschachtelte if-Anweisungen

if-Anweisungen können ineinander verschachtelt werden, um komplexere Logik zu verarbeiten.

Beispiel

void main() {
  bool isLoggedIn = true;
  bool isAdmin = false;
  String username = 'example';

  if (isLoggedIn) {
    // Äußere Prüfung: ob eingeloggt
    if (isAdmin) {
      // Innere Prüfung: ob Admin
      print(Willkommen zurück, Admin $username);
    } else {
      print(Willkommen zurück, $username);
    }
  } else {
    print(Bitte zuerst anmelden);
  }
}
欢迎回来,example

Zu viele Verschachtelungsebenen können die Lesbarkeit verringern; es wird empfohlen, nicht mehr als 3 Ebenen zu verwenden.

Wenn die Logik wirklich komplex ist, sollten Sie frühe Rückgaben oder das Aufteilen von Funktionen in Betracht ziehen, um sie zu vereinfachen.

Beispiel

Ersetzen von tiefer Verschachtelung durch frühe Rückgaben:

// Verwenden Sie frühe Rückgaben statt tiefer Verschachtelung für bessere Lesbarkeit
String getAccessMessage(bool isLoggedIn, bool isAdmin, String name) {
  // Zuerst den Fall 'return if condition not met' behandeln
  if (!isLoggedIn) {
    return Bitte melden Sie sich zuerst an;
  }

  if (!isAdmin) {
    return 'Sie haben keine Administratorberechtigungen';
  }

  // Schließlich die Hauptlogik
  return 'Willkommen zurück, Admin $name';
}

void main() {
  print(getAccessMessage(true, false, 'example'));
  print(getAccessMessage(true, true, 'example'));
}
你没有管理权限
欢迎回来,管理员 example

switch / case Mehrfachverzweigung

Wenn eine Variable mehrere feste mögliche Werte hat, ist switch klarer als if-else if.

Beispiel

void main() {
  String day = 'Mittwoch';

  switch (day) {
    case 'Montag':
      print('Eine neue Woche hat begonnen');
      break;  // break beendet den aktuellen case und verhindert 'fall-through' zum nächsten case
    case 'Dienstag':
      print('Der zweite Tag harter Arbeit');
      break;
    case 'Mittwoch':
      print('Mitte der Woche');
      break;
    case 'Donnerstag':
      print('Bald ist Freitag');
      break;
    case 'Freitag':
      print('TGIF!');
      break;
    case 'Samstag':
    case 'Sonntag':
      // Mehrere Fälle können sich einen Codeblock teilen
      print('Schönes Wochenende!');
      break;
    default:
      // Wird ausgeführt, wenn kein Fall übereinstimmt
      print('Unbekanntes Datum');
  }
}
The week is half over.

Der switch von Dart fällt nicht automatisch "durch"; jeder nicht leere case muss mit break, return, throw oder continue enden. Wenn Sie einen Fall-through-Effekt erzielen möchten, verwenden Sie continue mit einem Label.

switch-Ausdruck (Dart 3.0+)

Dart 3.0 hat switch-Ausdrücke eingeführt, die direkt Werte erzeugen können, wodurch die Syntax prägnanter wird.

Beispiel

void main() {
  String day = 'Mittwoch';

  // switch-Ausdruck: gibt direkt einen Wert zurück
  String mood = switch (day) {
    'Montag' => 'Ein wenig schläfrig',
    'Dienstag' => 'Beginne mich anzupassen',
    'Mittwoch' => 'Voller Energie',
    'Donnerstag' => 'Freue mich auf das Wochenende',
    'Freitag' => 'In fröhlicher Stimmung',
    'Samstag' || 'Sonntag' => 'Sorglos',
    _ => 'Unbekannt'  // _ ist ein Platzhalter, gleichbedeutend mit default
  };

  print('BEISPIEL-Stimmung: $mood');
}
EXAMPLE 心情: 干劲十足

switch-Ausdrücke erfordern, dass alle möglichen Fälle abgedeckt werden; der Compiler hilft Ihnen, Auslassungen zu erkennen.


for-Schleife

Die for-Schleife ist die häufigste Schleifenstruktur und eignet sich, wenn Sie die Anzahl der Iterationen kennen.

Standard-for-Schleife

Beispiel

void main() {
  // Standard-for-Schleife: Initialisierung; Bedingung; Aktualisierung
  for (int i = 1; i <= 5; i++) {
    print('EXAMPLE loop $i');
  }

  // Die Schleifenvariable kann auch außerhalb deklariert werden
  int j = 0;
  for (; j < 3; j++) {
    print('j = $j');
  }
}
EXAMPLE 第 1 次循环
EXAMPLE 第 2 次循环
EXAMPLE 第 3 次循环
EXAMPLE 第 4 次循环
EXAMPLE 第 5 次循环
j = 0
j = 1
j = 2

for-in-Schleife (Durchlaufen von Sammlungen)

for-in ist die einfachste Möglichkeit, über Sammlungen wie List und Set zu iterieren.

Beispiel

void main() {
  List<String> fruits = [Apple, Banana, Orange, 'Grape'];

  // for-in: durchläuft die Elemente in der Sammlung nacheinander
  for (var fruit in fruits) {
    print(EXAMPLE Fruit: $fruit);
  }
}
EXAMPLE 水果: 苹果
EXAMPLE 水果: 香蕉
EXAMPLE 水果: 橙子
EXAMPLE 水果: 葡萄

forEach-Methode

List und Set bieten auch die forEach-Methode, die eine Callback-Funktion verwendet, um jedes Element zu verarbeiten.

Beispiel

void main() {
  List<int> scores = [85, 92, 78, 60];

  // forEach: Führe die Callback-Funktion für jedes Element aus
  scores.forEach((score) {
    String result = score >= 60 ? 'Pass' : 'Fail';
    print(EXAMPLE Score: $score -> $result);
  });
}
EXAMPLE 分数: 85 -> 及格
EXAMPLE 分数: 92 -> 及格
EXAMPLE 分数: 78 -> 及格
EXAMPLE 分数: 60 -> 及格

while- und do-while-Schleifen

Die while-Schleife prüft die Bedingung vor jeder Iteration und eignet sich für Szenarien, in denen die Anzahl der Iterationen ungewiss ist.

Beispiel

void main() {
  // while: zuerst die Bedingung prüfen, dann ausführen
  int count = 3;
  while (count > 0) {
    print(EXAMPLE Countdown: $count);
    count--;  // Denke daran, die Bedingungsvariable zu aktualisieren, sonst wird es eine Endlosschleife
  }
  print(Launch!);
}
EXAMPLE 倒计时: 3
EXAMPLE 倒计时: 2
EXAMPLE 倒计时: 1
发射!

Der Unterschied zwischen do-while und while besteht darin, dass der Schleifenkörper mindestens einmal ausgeführt wird, weil die Bedingung am Ende geprüft wird.

Beispiel

void main() {
  // do-while: zuerst einmal ausführen, dann die Bedingung prüfen
  int num = 0;
  do {
    print(EXAMPLE wird mindestens einmal ausgeführt, num = $num);
    num++;
  } while (num < 0);  // Die Bedingung ist von Anfang an falsch

  print(Schleife beendet, num = $num);
}
EXAMPLE 至少执行一次,num = 0
循环结束,num = 1

Die do-while-Schleife garantiert, dass der Schleifenkörper mindestens einmal ausgeführt wird, selbst wenn die Bedingung von Anfang an nicht erfüllt ist. Dies ist nützlich in Szenarien wie "zuerst versuchen, dann auswerten", etwa beim Lesen von Benutzereingaben, bis sie gültig sind.

while vs for: Wie man wählt

SzenarienEmpfohlene SchleifeGrund
Bestimmte Anzahl von IterationenforInitialisierung, Bedingung und Aktualisierung zusammen geschrieben, auf einen Blick klar
Unbestimmte Anzahl von IterationenwhileNur auf die Bedingung konzentrieren, flexibler
Wird mindestens einmal ausgeführtdo-whileZuerst ausführen, dann auswerten
Sammlungen durchlaufenfor-in oder forEachDie prägnanteste Art, über Sammlungen zu iterieren

break und continue

break wird verwendet, um die gesamte Schleife sofort zu beenden, während continue verwendet wird, um die aktuelle Iteration zu überspringen und mit der nächsten fortzufahren.

Beispiel

void main() {
  // break: die Schleife sofort beenden, nachdem das Ziel gefunden wurde
  List<String> names = ['Alice', 'Bob', 'example', 'David'];

  for (var name in names) {
    print(Prüfen: $name);
    if (name == 'example') {
      print(BEISPIEL gefunden!);
      break;  // Die Schleife verlassen, die folgenden Elemente werden nicht mehr geprüft
    }
  }

  print(---Trennzeichen---);

  // continue: die aktuelle Iteration überspringen
  for (int i = 1; i <= 5; i++) {
    if (i == 3) {
      continue;  // die Iteration i=3 überspringen
    }
    print('BEISPIEL Iteration $i');
  }
}
检查: Alice
检查: Bob
检查: example
找到 EXAMPLE 了!
---分隔线---
EXAMPLE 第 1 次
EXAMPLE 第 2 次
EXAMPLE 第 4 次
EXAMPLE 第 5 次

Beschriftete break- und continue-Anweisungen

In verschachtelten Schleifen ermöglichen Labels es dir, aus einer bestimmten äußeren Schleife herauszuspringen.

Beispiel

void main() {
  // Das Label outerLoop markiert die äußere Schleife
  outerLoop:
  for (int i = 1; i <= 3; i++) {
    for (int j = 1; j <= 3; j++) {
      print('i=$i, j=$j');
      if (i == 2 && j == 2) {
        print('Ziel gefunden, äußere Schleife verlassen');
        break outerLoop;  // Aus der äußeren Schleife mit der Bezeichnung outerLoop ausbrechen
      }
    }
  }
  print('Schleife beendet');
}
i=1, j=1
i=1, j=2
i=1, j=3
i=2, j=1
i=2, j=2
找到目标,退出外层循环
循环结束

Labels sollten mit Vorsicht verwendet werden. In den meisten Fällen ist es klarer, die Logik verschachtelter Schleifen in unabhängige Funktionen auszulagern und return zum Verlassen zu verwenden.

Weitere Erweiterungen