Múltiplas variáveis no let: um problema que você não notava
Você já escreveu em Kotlin e de repente percebeu: "Preciso processar duas variáveis nullable ao mesmo tempo"? Você recorre ao seu amado let, mas... pare. O let funciona apenas com uma variável. E o que fazer se você tiver duas, três ou mais?
Esta pergunta é uma das mais populares no Stack Overflow sobre Kotlin. Milhares de desenvolvedores tropeçam nesta tarefa aparentemente simples. E hoje vamos entender de uma vez por todas como resolvê-la de forma elegante e correta.
Neste artigo, não vamos apenas dar exemplos secos. Vamos comparar 3 abordagens, discutir seus prós, contras e best practices. Você aprenderá qual método escolher dependendo da situação e deixará de escrever let aninhados feios.
Por que o problema "Multiple variable let" é tão popular?
Kotlin é uma linguagem que adora null safety. As funções de escopo (scope functions) — let, run, with, apply, also — são nossa arma secreta para trabalhar com segurança com tipos nullable. Mas elas têm uma limitação: cada função é projetada para um único objeto receptor.
Imagine a situação: você recebe de uma API dois campos nullable — o nome do usuário e seu email. Você precisa verificar se ambos não são null e só então executar uma ação (por exemplo, enviar um email de boas-vindas).
Iniciantes geralmente escrevem assim:
val name: String? = getUserName()val email: String? = getUserEmail()
if (name != null && email != null) { sendWelcomeEmail(name, email)}Isso funciona, mas não é o jeito Kotlin. Podemos tornar o código mais conciso e seguro. Vamos ver como.
Abordagem 1: let aninhados — simples, mas feio
A maneira mais óbvia é aninhar um let dentro do outro. É a primeira coisa que vem à mente:
val name: String? = getUserName()val email: String? = getUserEmail()
name?.let { safeName -> email?.let { safeEmail -> sendWelcomeEmail(safeName, safeEmail) }}Prós:
- Funciona "de fábrica", não requer funções adicionais
- O código é lido sequencialmente
Contras:
- Ao aumentar o número de variáveis (3, 4 ou mais), o código se transforma em uma "pirâmide do terror"
- Difícil de ler e manter
- Cada nível aninhado adiciona um recuo extra
Esta abordagem só é adequada para duas variáveis. Para três ou mais, procure uma alternativa.
Abordagem 2: Usando Pair, Triple e data class
Kotlin fornece as classes embutidas Pair e Triple. A ideia é combinar variáveis nullable em um único objeto e depois verificá-lo através do let.
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)}Para três variáveis, usamos 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)}Prós:
- Sem aninhamento profundo na chamada final
- A desestruturação torna o código limpo
Contras:
- O aninhamento interno (ao criar Pair/Triple) ainda existe
Tripleé o máximo para a biblioteca padrão. Para 4+ variáveis, você precisa