Menu
Coddy logo textTech

Late-Schlüsselwort und Null-Sicherheit

Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy. Lektion 26 von 110.

Manchmal benötigst du eine nicht-nullbare Variable, aber du kannst ihr nicht sofort einen Wert zuweisen. Das Schlüsselwort late teilt Dart mit: „Ich verspreche, diese Variable zu initialisieren, bevor ich sie verwende.“

late String description;

void setup() {
  description = 'Initialized later';
}

void main() {
  setup();
  print(description);  // Funktioniert - vor der Verwendung initialisiert
}

Ohne late würde Dart sich beschweren, dass description nicht initialisiert ist. Mit late übernimmst du die Verantwortung dafür, sicherzustellen, dass es vor dem Zugriff einen Wert hat. Wenn du versuchst, es vor der Initialisierung zu lesen, erhältst du einen Laufzeitfehler.

Ein häufiger Anwendungsfall sind aufwendige Berechnungen, deren Ausführung du verzögern möchtest, bis sie tatsächlich benötigt werden:

class DataProcessor {
  late List<int> data = _loadData();
  
  List<int> _loadData() {
    print('Loading data...');
    return [1, 2, 3, 4, 5];
  }
}

DataProcessor processor = DataProcessor();
// 'Loading data...' wurde noch nicht ausgegeben
print(processor.data);  // Jetzt wird es geladen und ausgegeben

Die Methode _loadData() wird nur ausgeführt, wenn auf data zum ersten Mal zugegriffen wird, nicht wenn das Objekt erstellt wird. Diese verzögerte Initialisierung kann die Leistung verbessern, wenn der Wert möglicherweise nie benötigt wird.

Verwende late, wenn du sicher bist, dass eine Variable vor ihrer Verwendung initialisiert wird, dies aber bei der Deklaration nicht möglich ist. Es ist ein Versprechen an den Compiler – brichst du dieses Versprechen, stürzt dein Programm ab.

challenge icon

Aufgabe

Einfach

Lass uns einen Konfigurationsmanager erstellen, der die Leistungsfähigkeit von late-Variablen für die verzögerte Initialisierung demonstriert. Du erstellst ein System, bei dem aufwendige Einrichtungsvorgänge erst ausgeführt werden, wenn die Konfiguration tatsächlich benötigt wird.

Du organisierst deinen Code in zwei Dateien:

  • config_manager.dart: Definiere eine ConfigManager-Klasse, die Anwendungseinstellungen verwaltet. Die Klasse sollte Folgendes enthalten:
    • Eine über den Konstruktor übergebene Variable String appName
    • Eine late String databaseUrl-Variable, die später über eine Einrichtungsmethode initialisiert wird
    • Eine late int maxConnections-Variable mit verzögerter Initialisierung, die beim ersten Zugriff Calculating max connections... ausgibt und 100 zurückgibt
    • Eine setupDatabase(String url)-Methode, die databaseUrl initialisiert
    • Eine displayConfig()-Methode, die die aktuelle Konfiguration ausgibt
  • main.dart: Importiere deinen Konfigurationsmanager und demonstriere, wie late-Variablen funktionieren:
    • Erstelle einen ConfigManager mit dem Anwendungsnamen 'MyApp'
    • Gib Config created aus
    • Rufe setupDatabase mit der URL 'localhost:5432/mydb' auf
    • Gib Accessing max connections... aus
    • Gib den Wert von maxConnections aus
    • Gib Accessing max connections again... aus
    • Gib den Wert von maxConnections erneut aus (beachte, dass die Berechnungsmeldung nicht wiederholt wird)
    • Rufe displayConfig() auf

Die displayConfig()-Methode sollte in diesem Format ausgeben:

--- Configuration ---
App: [appName]
Database: [databaseUrl]
Max Connections: [maxConnections]

Beachte, dass die verzögerte Berechnung von maxConnections nur einmal ausgeführt wird – beim ersten Zugriff darauf. Das ist der Vorteil von late mit einem Initialisierer!

Erwartete Ausgabe:

Config created
Accessing max connections...
Calculating max connections...
100
Accessing max connections again...
100
--- Configuration ---
App: MyApp
Database: localhost:5432/mydb
Max Connections: 100

Probier es selbst

import 'config_manager.dart';

void main() {
  // TODO: Erstelle einen ConfigManager mit dem App-Namen 'MyApp'
  
  // TODO: Print 'Config created'
  
  // TODO: Call setupDatabase with URL 'localhost:5432/mydb'
  
  // TODO: Print 'Accessing max connections...'
  
  // TODO: Print the value of maxConnections
  
  // TODO: Print 'Accessing max connections again...'
  
  // TODO: Print the value of maxConnections again
  // (beachte, dass die Berechnungsmeldung sich nicht wiederholt)
  
  // TODO: Rufe displayConfig() auf
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-Dart-Compiler