«Eu acabei de verificar!» — a dor familiar de todo desenvolvedor Kotlin
\nVocê está programando em Kotlin, aproveitando sua concisão e segurança, quando de repente — uma linha vermelha ondulada. O compilador exibe: Smart cast to 'Type' is impossible, because 'variable' is a mutable property that could have been changed by this time. Familiar? Se você já enfrentou esse erro pelo menos uma vez, não está sozinho. Esta questão é uma das mais populares no Stack Overflow, e não é à toa: ela levanta um tópico fundamental — como o Kotlin nos protege de nós mesmos.
Neste artigo, não vamos apenas analisar por que o erro ocorre, mas também mostrar como contorná-lo elegantemente em 2025. Você aprenderá o que é smart cast (conversão inteligente), por que o Kotlin não confia em propriedades mutáveis e quais melhores práticas ajudarão a escrever código limpo e seguro sem "gambiarras" desnecessárias. Vamos lá!
\n\nO que é smart cast e por que ele é "inteligente"?
\nUm dos pontos fortes do Kotlin é a conversão inteligente de tipos. É quando o compilador entende por conta própria que, após verificar o tipo de uma variável, ela pode ser usada como aquele tipo, sem conversão explícita. Por exemplo:
\nfun printLength(obj: Any) {\n if (obj is String) {\n // Smart cast: obj automaticamente se tornou String\n println(obj.length)\n }\n}\nBonito, não é? O compilador vê: "Ah, verificamos que obj é uma String, então dentro do bloco if ele é definitivamente uma string, podemos chamar length". Isso é o smart cast.
\nMas há um detalhe: esse truque só funciona se o compilador puder garantir que a variável não mudará entre a verificação e o uso. Agora, se a variável for var (mutável), não há garantias. E é aí que a diversão começa.
A raiz do problema: mutable property (propriedade mutável)
\nVamos ver um exemplo típico que causa o erro:
\nclass UserRepository {\n var currentUser: User? = null\n\n fun printUserName() {\n if (currentUser != null) {\n // Erro! Smart cast to 'User' is impossible\n // porque currentUser é var e pode ter mudado\n println(currentUser.name)\n }\n }\n}\nQual é o problema? Acabamos de verificar que currentUser não é nulo! O compilador responde: "Amigo, você está usando var. Isso significa que entre a verificação e a chamada do println, outra thread (ou até mesmo este mesmo código em outro lugar) poderia ter alterado currentUser de volta para null. Não posso arriscar — e se der NPE?".
E isso é correto! Kotlin é uma linguagem com filosofia null-safe. Ela não permite que você atire no próprio pé. Mesmo que você tenha certeza de que ninguém alterará a propriedade, o compilador age com segurança. Isso é melhor do que pegar um NullPointerException em tempo de execução.
Como corrigir isso? 5 maneiras comprovadas (edição 2025)
\nA boa notícia: existem várias soluções, e todas são simples. Escolha a que melhor se adapta ao seu estilo de código e situação.
\n\n1. Cópia local imutável (a mais confiável)
\nO caminho mais direto é salvar o valor em um val (variável local imutável). O compilador vê imediatamente que o val local não será alterado por ninguém, e o smart cast funciona:
fun printUserName() {\n val user = currentUser\n if (user != null) {\n // Smart cast funciona! user é um val local\n println(user.name)\n }\n}\nEssa técnica é o padrão ouro. É simples, legível e não requer bibliotecas adicionais. Em 2025, continua sendo a maneira mais recomendada.
\n\n2. Função let (maneira elegante)
\nA função let é uma excelente ferramenta para trabalhar com valores nullable. Ela executa um bloco de código apenas se o objeto não for nulo, e dentro do bloco o objeto fica disponível como it (ou você pode dar um nome):
Blogs
Book Recommendations
Leia também
Operadores condicionais match case e comparações em Python: do if aos padrões