Mehrere Variablen in let: Ein Problem, das Sie nicht bemerkt haben
Haben Sie jemals in Kotlin programmiert und plötzlich gedacht: "Ich muss zwei nullable Variablen gleichzeitig verarbeiten"? Sie greifen zu Ihrem geliebten let, aber... stopp. let funktioniert nur mit einer Variablen. Was aber, wenn Sie zwei, drei oder mehr haben?
Diese Frage ist eine der beliebtesten auf Stack Overflow zum Thema Kotlin. Tausende Entwickler stolpern über diese scheinbar einfache Aufgabe. Und heute werden wir ein für alle Mal klären, wie man sie elegant und korrekt löst.
In diesem Artikel geben wir nicht nur trockene Beispiele. Wir vergleichen 3 Ansätze, diskutieren ihre Vor- und Nachteile und best practices. Sie erfahren, welche Methode Sie je nach Situation wählen, und hören auf, hässliche verschachtelte let zu schreiben.
Warum ist das Problem "Multiple variable let" so beliebt?
Kotlin ist eine Sprache, die null safety liebt. Die Bereichsfunktionen (scope functions) — let, run, with, apply, also — sind unsere Geheimwaffe für die sichere Arbeit mit nullable Typen. Aber sie haben eine Einschränkung: Jede Funktion ist für ein einzelnes Empfängerobjekt ausgelegt.
Stellen Sie sich eine Situation vor: Sie erhalten aus einer API zwei nullable Felder – den Benutzernamen und seine E-Mail. Sie müssen prüfen, dass beide nicht null sind, und erst dann eine Aktion ausführen (z. B. eine Willkommens-E-Mail senden).
Anfänger schreiben oft so:
val name: String? = getUserName()val email: String? = getUserEmail()
if (name != null && email != null) { sendWelcomeEmail(name, email)}Das funktioniert, ist aber nicht der Kotlin-Way. Wir können den Code prägnanter und sicherer machen. Schauen wir uns an, wie.
Ansatz 1: Verschachtelte let – einfach, aber nicht schön
Der offensichtlichste Weg ist, ein let in ein anderes zu verschachteln. Das ist das Erste, was einem in den Sinn kommt:
val name: String? = getUserName()val email: String? = getUserEmail()
name?.let { safeName -> email?.let { safeEmail -> sendWelcomeEmail(safeName, safeEmail) }}Vorteile:
- Funktioniert "out of the box", erfordert keine zusätzlichen Funktionen
- Der Code liest sich sequenziell
Nachteile:
- Bei einer steigenden Anzahl von Variablen (3, 4 und mehr) wird der Code zur "Pyramide des Schreckens"
- Schwer zu lesen und zu warten
- Jede Verschachtelungsebene fügt einen zusätzlichen Einzug hinzu
Dieser Ansatz eignet sich nur für zwei Variablen. Für drei oder mehr suchen Sie nach einer Alternative.
Ansatz 2: Verwendung von Pair, Triple und data class
Kotlin bietet die eingebauten Klassen Pair und Triple. Die Idee ist, nullable Variablen in einem Objekt zu bündeln und es dann mit let zu prüfen.
val name: String? = getUserName()val email: String? = getUserEmail()
val pair = name?.let { n -> email?.let { e -> n to e }}
pair?.let { (safeName, safeEmail) -> sendWelcomeEmail(safeName, safeEmail)}Für drei Variablen verwenden wir Triple:
val name: String? = getUserName()val email: String? = getUserEmail()val age: Int? = getUserAge()
val triple = name?.let { n -> email?.let { e -> age?.let { a -> Triple(n, e, a) } }}
triple?.let { (safeName, safeEmail, safeAge) -> sendWelcomeEmail(safeName, safeEmail, safeAge)}Vorteile:
- Keine tiefe Verschachtelung im finalen Aufruf
- Destrukturierung macht den Code sauber
Nachteile:
- Die innere Verschachtelung (beim Erstellen von Pair/Triple) ist immer noch vorhanden
Tripleist das Maximum für die Standardbibliothek. Für 4+ Variablen benötigt man