var e val em Kotlin: qual a diferença? Análise completa
Se você está apenas começando sua jornada em Kotlin ou veio de outras linguagens (Java, Python, JavaScript), uma das primeiras perguntas que fará é: por que são necessárias duas palavras-chave para declarar variáveis? Realmente, por que complicar se podemos usar apenas uma? A resposta está na filosofia da linguagem: Kotlin foi criado para tornar o código mais seguro, claro e previsível. E a diferença entre var e val não é um capricho, mas uma ferramenta poderosa para gerenciamento de estado.
Vamos entender com exemplos quando usar var e quando usar val, e por que isso é importante para o seu código.
O que são var e val? Definições básicas
Vamos começar pelo mais simples.
var(do inglês variable) — variável mutável. Você pode reatribuir um novo valor a ela quantas vezes quiser.val(do inglês value) — referência imutável (somente leitura). Após a inicialização, você não pode alterar seu valor. É análogo aofinalem Java ouconstem JavaScript (com ressalvas).
Aqui está o exemplo mais simples:
fun main() { var x = 10 x = 20 // OK: var pode ser alterado
val y = 30 // y = 40 // Erro de compilação: val não pode ser reatribuído
println("x = $x, y = $y")}Tudo parece óbvio, mas o diabo, como sempre, está nos detalhes.
Diferença principal: mutabilidade da referência vs mutabilidade do objeto
Aqui surge confusão com frequência. val garante que a referência ao objeto não mudará, mas não garante a imutabilidade do objeto em si.
Vamos analisar com um exemplo de lista:
fun main() { val numbers = mutableListOf(1, 2, 3) // numbers = mutableListOf(4, 5, 6) // Erro: val não pode ser reatribuído
numbers.add(4) // Mas assim — pode! Estamos alterando o conteúdo do objeto numbers[0] = 100 // E assim também pode
println(numbers) // [100, 2, 3, 4]}Observe: declaramos numbers como val, mas adicionamos e alteramos elementos tranquilamente. Por quê? Porque val protege apenas a referência em si (a variável numbers), e não o objeto para o qual ela aponta.
Se você deseja imutabilidade completa, precisa usar coleções imutáveis (listOf, mapOf, setOf) e val simultaneamente.
fun main() { val immutableNumbers = listOf(1, 2, 3) // immutableNumbers.add(4) // Erro: listOf retorna uma lista imutável // immutableNumbers[0] = 100 // Erro}Este é um ponto importante que frequentemente é perguntado em entrevistas. Lembre-se: val ≠ objeto imutável.
Quando usar var e quando usar val?
A regra de ouro do Kotlin: use val sempre que possível, e var apenas quando realmente necessário. Por quê?
- Segurança. Quanto menos variáveis mutáveis, menor a chance de alterar acidentalmente um valor em um local inesperado. Isso é especialmente importante em programação multithread.
- Legibilidade. Quando você vê
val, sabe imediatamente que o valor não mudará. Isso simplifica a compreensão do código. - Estilo funcional. Kotlin incentiva a programação funcional, onde a imutabilidade é um dos princípios-chave.
Aqui está um exemplo onde var é justificado:
fun main() { var counter = 0 while (counter < 10) { println("Counter: $counter") counter++ // O contador precisa mudar }}E aqui está um exemplo onde var é uma má prática e pode ser substitu