Callbackfunktion - flutter-tutorial-de/dart-programming GitHub Wiki

Table of Contents

Zielsetzung

In Dart ist es erlaubt, Funktionen als Parameter an Funktionen oder Methoden zu übergeben. Das erhöht die Wiederverwendbarkeit von Programmcode.

Beispiel

  • Eine Filterfunktion soll aus einer Liste von Strings nur diejenigen Einträge ausgeben, die mit einem gegebenen String anfangen:
List<String> filterStartsWith(List<String> list){
  for (line in list){
    if (line.startsWith('Hallo')){
      print(line);
    }
  }
}
  • Eine zweite Filterfunktion soll nur die Einträge ausgeben, die mit einem bestimmten String enden:
List<String> filterEndsWith(List<String> list){
  for (line in list){
    if (line.endsWith('Kuss')){
      print(line);
    }
  }
}
  • Die zwei Funktionen unterscheiden sich nur in der Bedingung line.startsWith() bzw. line.endsWith().

Mit Callbackfunktion

Wir formulieren die Funktion so um, dass die Bedingungsfunktion per Parameter mitgegeben wird:

Hinweis: Der Datentyp einer Funktion ist Function.

List<String> filterList(Function filter, List<String> list){
  for (line in list){
    if (filter(line)){
      print(line);
    }
  }
}
Wir definieren dann die eigentlichen Filterfunktionen, die nur den Vergleich durchführen:
bool filterHallo(String line) => line.startsWith('Hallo');
bool filterKuss(String line) => line.endswith('Kuss');
  • filterHallo() liefert genau dann true zurück, wenn line mit Hallo anfängt, sonst false.
  • filterEndsWith() liefert genau dann true zurück, wenn line mit Kuss aufhört, andernfalls false.
Abschließend rufen wir die filterList()-Funktion mit folgendem Befehl auf:
final list =  ['Hallo Welt', 'Gruß und Kuss'];
filterList(filterHallo, list);
filterList(filterKuss, list);
Hier die Zusammenfassung in einem in dartpad.dev ausführbaren Format:
typedef Filter = bool Function (String);
void filterList(Filter filter, List<String> list){
  for (var line in list){
    if (filter(line)){
      print(line);
    }
  }
}
void main(){
  final list =  ['Hallo Welt', 'Gruß und Kuss'];
  bool filterHallo(String line) => line.startsWith('Hallo');
  filterList(filterHallo, list);
  bool filterKuss(String line) => line.endsWith('Kuss');
  filterList(filterKuss, list);
}
  • typedef Filter = bool Function (String); Hier definieren wir einen neuen Datentyp namens Filter, der eine Funktion beschreibt, deren Ergebnistyp bool ist und die als Parameter einen String enthält.
  • Der erste Parameter von filterList() wird damit genauer beschrieben also nur mit "ist eine Funktion" und der Compiler erkennt einen Fehler, wenn als Parameter beispielsweise folgende Funktion übergeben wird: int length(String line) => line.length; Hinweis: Der Ergebnistyp ist int statt bool.

Namenlose Funktion

Wir können das obige Beispiel noch mehr vereinfachen: Wir definieren keine eigene benannte Funktion filterHallo() mehr, sondern fügen die Bedingung gleich in den Parameter ein. Das gleiche geschieht mit der Funktion filterKuss():

typedef Filter = bool Function (String);
void filterList(Filter filter, List<String> list){
  for (var line in list){
    if (filter(line)){
      print(line);
    }
  }
}
void main(){
  final list =  ['Hallo Welt', 'Gruß und Kuss'];
  filterList((String line) => line.startsWith('Hallo'), list);
  filterList((String line) => line.endsWith('Kuss'), list);
}
  • filterList((String line) => line.startsWith('Hallo'), list); Als erster Parameter taucht die Funktionsdefinition auf, in der aber kein Name steht: (String line) => line.startsWith('Hallo').
  • Diese Art von Funktion wird namenlose Funktion oder Lambda-Funktion genannt.
  • Wir können eine Lambda-Funktion auch in einer Variablen speichern:
final filterHallo = (String line) => line.startsWith('Hallo');
final gefunden = filterHallo('Text mit "Hallo"');
  • Da die Variable filterHallo eine Funktion als Wert hat, können wir diese Funktion mit filterHallo('Text mit "Hallo"') aufrufen, das Ergebnis ist ein Wahrheitswert, hier true.

Anwendung in Containern

Die Containerklassen List, Map und Set machen ausführlich Gebrauch von "Funktion als Parameter".

⚠️ **GitHub.com Fallback** ⚠️