Cheatsheet Kotlin: Referência Rápida em Português

Este cheatsheet reúne os principais conceitos e sintaxes de Kotlin em um único lugar. Ideal para consulta rápida durante o desenvolvimento ou para revisão antes de entrevistas. Se você está começando, confira nosso Guia Completo de Kotlin para uma introdução mais detalhada.


1. Variáveis e Tipos

Kotlin diferencia entre variáveis imutáveis (val) e mutáveis (var). O compilador infere tipos automaticamente na maioria dos casos.

// val = imutável (recomendado), var = mutável
val nome: String = "Kotlin"
val versao = 2.1              // tipo inferido: Int
var contador = 0               // mutável, pode ser reatribuído
contador += 1

// Tipos básicos
val inteiro: Int = 42
val longo: Long = 100_000_000L
val decimal: Double = 3.14
val flutuante: Float = 2.7f
val caractere: Char = 'K'
val booleano: Boolean = true
val texto: String = "Olá, Kotlin!"

// Nullable types - adicione ? para permitir null
val nomeOpcional: String? = null
val idadeOpcional: Int? = null

// Tipos especiais
val qualquerCoisa: Any = "pode ser qualquer tipo"  // raiz da hierarquia
val semRetorno: Unit = Unit                         // equivalente a void
// Nothing - tipo que nunca tem valor (funções que sempre lançam exceção)
fun falhar(): Nothing = throw IllegalStateException("Erro fatal")

Veja mais sobre tipos nullable no glossário.


2. Controle de Fluxo

Em Kotlin, if e when são expressões que retornam valores, não apenas statements.

// if como expressão
val max = if (a > b) a else b

// when - substituto poderoso do switch
val descricao = when (codigo) {
    1 -> "Sucesso"
    2, 3 -> "Aviso"
    in 400..499 -> "Erro do cliente"
    in 500..599 -> "Erro do servidor"
    else -> "Desconhecido"
}

// when sem argumento (substitui if-else encadeado)
val faixa = when {
    idade < 13 -> "criança"
    idade < 18 -> "adolescente"
    idade < 60 -> "adulto"
    else -> "idoso"
}

// when exaustivo com sealed class
sealed class Resultado
data class Sucesso(val dados: String) : Resultado()
data class Erro(val mensagem: String) : Resultado()

val texto = when (resultado) {
    is Sucesso -> resultado.dados      // smart cast automático
    is Erro -> resultado.mensagem
    // não precisa de else - sealed é exaustivo
}

// for com ranges e coleções
for (i in 1..10) println(i)           // 1 até 10, inclusive
for (i in 0 until 10) println(i)      // 0 até 9
for (i in 10 downTo 0 step 2) println(i) // 10, 8, 6, 4, 2, 0
for ((indice, valor) in lista.withIndex()) {
    println("$indice: $valor")
}

// while e do-while
while (condicao) { /* ... */ }
do { /* ... */ } while (condicao)

// Labels para break e continue
externo@ for (i in 1..10) {
    for (j in 1..10) {
        if (j == 5) continue@externo  // pula para próxima iteração do loop externo
        if (i == 3) break@externo     // sai dos dois loops
    }
}

3. Funções

Kotlin oferece funções de primeira classe, com suporte a extension functions, lambdas e higher-order functions. Leia nosso post sobre extension functions para exemplos práticos.

// Função básica
fun somar(a: Int, b: Int): Int {
    return a + b
}

// Função de expressão única
fun somar(a: Int, b: Int): Int = a + b

// Parâmetros padrão e argumentos nomeados
fun criarUsuario(
    nome: String,
    email: String,
    ativo: Boolean = true,
    papel: String = "usuario"
): Usuario = Usuario(nome, email, ativo, papel)

val admin = criarUsuario(
    nome = "Ana",
    email = "ana@email.com",
    papel = "admin"    // argumentos nomeados em qualquer ordem
)

// Extension functions - adiciona métodos a classes existentes
fun String.capitalizar(): String =
    this.lowercase().replaceFirstChar { it.uppercase() }

println("kOTLIN".capitalizar())  // "Kotlin"

// Funções infix
infix fun Int.vezes(str: String): String = str.repeat(this)
val resultado = 3 vezes "Olá "  // "Olá Olá Olá "

// Operator overloading
data class Vetor(val x: Double, val y: Double) {
    operator fun plus(outro: Vetor) = Vetor(x + outro.x, y + outro.y)
    operator fun times(escalar: Double) = Vetor(x * escalar, y * escalar)
}

val v = Vetor(1.0, 2.0) + Vetor(3.0, 4.0)  // Vetor(4.0, 6.0)

// Higher-order functions e lambdas
fun <T> List<T>.filtrarCustomizado(predicado: (T) -> Boolean): List<T> {
    val resultado = mutableListOf<T>()
    for (item in this) {
        if (predicado(item)) resultado.add(item)
    }
    return resultado
}

val pares = (1..20).toList().filtrarCustomizado { it % 2 == 0 }

// Lambda com múltiplos parâmetros
val calcular: (Int, Int) -> Int = { a, b -> a * b }

Saiba mais sobre operator overloading no glossário.


4. Null Safety

O sistema de null safety de Kotlin elimina NullPointerException em tempo de compilação. Veja o glossário de nullable e o glossário de lateinit para mais detalhes.

// Tipos nullable precisam de ? no tipo
var nome: String? = "Kotlin"
nome = null  // permitido

// Safe call operator (?.)
val tamanho: Int? = nome?.length  // null se nome for null

// Elvis operator (?:)
val tamanhoSeguro: Int = nome?.length ?: 0  // 0 se nome for null
val nomeSeguro: String = nome ?: throw IllegalArgumentException("Nome obrigatório")

// Not-null assertion (!!) - use com cuidado!
val tamanhoForced: Int = nome!!.length  // lança NPE se null

// Scope functions com null safety
nome?.let { nomeNaoNull ->
    println("Nome tem ${nomeNaoNull.length} caracteres")
}

// also - executa bloco e retorna o objeto original
val usuario = buscarUsuario()?.also { log.info("Encontrou: ${it.nome}") }

// apply - configura objeto e retorna ele mesmo
val config = Configuracao().apply {
    host = "localhost"
    porta = 8080
    ssl = true
}

// run - executa bloco no contexto do objeto
val comprimento = nome?.run {
    println("Processando: $this")
    length  // retorna o último valor
}

// Safe cast
val numero: Any = "123"
val inteiro: Int? = numero as? Int  // null em vez de ClassCastException

// lateinit - inicialização tardia (não-null garantido pelo programador)
lateinit var servico: MeuServico

// lazy - inicialização preguiçosa (thread-safe por padrão)
val dadosCache: List<String> by lazy {
    carregarDoBanco()  // executado apenas na primeira chamada
}

5. Classes e OOP

Kotlin tem suporte completo a orientação a objetos com data classes, sealed classes, companion objects e mais. Confira nosso guia de Design Patterns em Kotlin.

// Classe com construtor primário
class Pessoa(val nome: String, var idade: Int) {
    // Bloco init executado durante a construção
    init {
        require(idade >= 0) { "Idade não pode ser negativa" }
    }

    // Construtor secundário
    constructor(nome: String) : this(nome, 0)
}

// Data class - gera equals, hashCode, toString, copy, componentN
data class Usuario(
    val id: Long,
    val nome: String,
    val email: String
)

val u1 = Usuario(1, "Ana", "ana@email.com")
val u2 = u1.copy(nome = "Maria")  // cópia com alteração
val (id, nome, email) = u1         // destructuring

// Sealed class - hierarquia restrita (exaustiva no when)
sealed class Estado {
    object Carregando : Estado()
    data class Sucesso(val dados: List<String>) : Estado()
    data class Erro(val exception: Throwable) : Estado()
}

// Sealed interface (Kotlin 1.5+)
sealed interface Operacao {
    data class Criar(val item: String) : Operacao
    data class Deletar(val id: Int) : Operacao
}

// Enum class
enum class Cor(val hex: String) {
    VERMELHO("#FF0000"),
    VERDE("#00FF00"),
    AZUL("#0000FF");

    fun escurecer(): String = "dark-$hex"
}

// Object - singleton
object Logger {
    fun info(msg: String) = println("[INFO] $msg")
}

// Companion object - equivalente a membros estáticos
class Fabrica {
    companion object {
        fun criar(): Fabrica = Fabrica()
        const val VERSAO = "1.0"
    }
}
val f = Fabrica.criar()

// Interface com implementação padrão
interface Repositorio<T> {
    fun buscar(id: Long): T?
    fun salvar(item: T): T
    fun deletar(id: Long): Boolean = false  // implementação padrão
}

// Herança - classes são final por padrão, use open
open class Animal(val nome: String) {
    open fun falar(): String = "..."
}
class Cachorro(nome: String) : Animal(nome) {
    override fun falar(): String = "Au au!"
}

// Abstract class
abstract class Forma {
    abstract fun area(): Double
    fun descricao(): String = "Forma com área ${area()}"
}

Leia mais sobre interfaces e delegation no glossário.


6. Collections

Kotlin diferencia entre coleções imutáveis e mutáveis, com uma rica API funcional para transformações.

// Criação de coleções
val listaImutavel: List<String> = listOf("a", "b", "c")
val listaMutavel: MutableList<String> = mutableListOf("a", "b", "c")
val mapa: Map<String, Int> = mapOf("um" to 1, "dois" to 2)
val mapaMutavel = mutableMapOf<String, Int>()
val conjunto: Set<Int> = setOf(1, 2, 3, 3)  // {1, 2, 3}

// Transformações funcionais
val numeros = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

val pares = numeros.filter { it % 2 == 0 }           // [2, 4, 6, 8, 10]
val dobrados = numeros.map { it * 2 }                 // [2, 4, 6, ..., 20]
val soma = numeros.reduce { acc, n -> acc + n }        // 55
val somaInicial = numeros.fold(100) { acc, n -> acc + n } // 155

// flatMap - achata listas aninhadas
val frases = listOf("Olá mundo", "Kotlin é legal")
val palavras = frases.flatMap { it.split(" ") }  // [Olá, mundo, Kotlin, é, legal]

// groupBy e associate
data class Produto(val categoria: String, val nome: String, val preco: Double)

val produtos = listOf(
    Produto("frutas", "Maçã", 3.5),
    Produto("frutas", "Banana", 2.0),
    Produto("legumes", "Cenoura", 4.0)
)

val porCategoria = produtos.groupBy { it.categoria }
// {frutas=[Maçã, Banana], legumes=[Cenoura]}

val precos = produtos.associate { it.nome to it.preco }
// {Maçã=3.5, Banana=2.0, Cenoura=4.0}

// Sequences - avaliação preguiçosa para coleções grandes
val resultado = (1..1_000_000).asSequence()
    .filter { it % 3 == 0 }
    .map { it * it }
    .take(10)
    .toList()

// Outras operações úteis
numeros.first { it > 5 }        // 6
numeros.any { it > 9 }          // true
numeros.all { it > 0 }          // true
numeros.none { it < 0 }         // true
numeros.partition { it > 5 }    // Pair([6,7,8,9,10], [1,2,3,4,5])
numeros.chunked(3)               // [[1,2,3], [4,5,6], [7,8,9], [10]]
numeros.zip(numeros.reversed())  // [(1,10), (2,9), ...]

7. Strings e Formatação

// String templates
val nome = "Kotlin"
val versao = 2.1
println("Usando $nome versão $versao")            // interpolação simples
println("${nome.length} caracteres no nome")       // expressão
println("Preço: R$ ${"%.2f".format(19.9)}")        // formatação dentro do template

// Raw strings (multiline)
val json = """
    {
        "nome": "$nome",
        "versao": $versao
    }
""".trimIndent()

val regex = """(\d{3})\.(\d{3})\.(\d{3})-(\d{2})""".toRegex()
val cpfValido = regex.matches("123.456.789-00")  // true

// Métodos úteis de String
"  kotlin  ".trim()                // "kotlin"
"kotlin".uppercase()               // "KOTLIN"
"KOTLIN".lowercase()               // "kotlin"
"kotlin".replaceFirstChar { it.uppercase() }  // "Kotlin"
"um,dois,tres".split(",")          // [um, dois, tres]
"kotlin".padStart(10, '-')         // "---kotlin"
"kotlin".repeat(3)                 // "kotlinkotlinkotlin"
"kotlin" in "eu amo kotlin!"       // true (contains)

// buildString - construção eficiente de strings
val html = buildString {
    appendLine("<html>")
    appendLine("  <body>")
    appendLine("    <h1>Olá, $nome!</h1>")
    appendLine("  </body>")
    appendLine("</html>")
}

// Regex avançado
val padrao = """\b[A-Z]\w+""".toRegex()
val nomes = padrao.findAll("Ana vai ao mercado com Bruno")
    .map { it.value }
    .toList()  // [Ana, Bruno]

8. Tratamento de Erros

// try/catch como expressão
val numero: Int = try {
    "abc".toInt()
} catch (e: NumberFormatException) {
    0  // valor padrão
} finally {
    println("Tentativa concluída")
}

// runCatching + Result type (abordagem funcional)
val resultado: Result<Int> = runCatching {
    riskyOperation()
}

resultado
    .onSuccess { valor -> println("Sucesso: $valor") }
    .onFailure { erro -> println("Erro: ${erro.message}") }

val valorOuPadrao = resultado.getOrDefault(0)
val valorOuCalculo = resultado.getOrElse { erro ->
    log.warn("Fallback usado: ${erro.message}")
    calcularAlternativa()
}

// Encadeamento com Result
val processado = runCatching { buscarDados() }
    .mapCatching { dados -> transformar(dados) }
    .mapCatching { transformado -> salvar(transformado) }
    .getOrElse { erro -> Resultado.vazio() }

// require e check - preconditions
fun processarIdade(idade: Int) {
    require(idade >= 0) { "Idade deve ser não-negativa, recebeu: $idade" }
    // IllegalArgumentException se falhar
}

fun executar() {
    check(estado == Estado.PRONTO) { "Sistema não está pronto" }
    // IllegalStateException se falhar
}

// Exceção customizada
class UsuarioNaoEncontradoException(
    val userId: Long
) : RuntimeException("Usuário $userId não encontrado")

9. Coroutines

Coroutines são a base da programação assíncrona em Kotlin. Leia nosso guia completo de coroutines e o post sobre Kotlin Flow.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

// Função suspensa - pode ser pausada e retomada
suspend fun buscarUsuario(id: Long): Usuario {
    return withContext(Dispatchers.IO) {
        api.buscar(id)  // operação de I/O
    }
}

// launch - dispara coroutine sem resultado (fire-and-forget)
val scope = CoroutineScope(Dispatchers.Default)
scope.launch {
    val usuario = buscarUsuario(1)
    println(usuario.nome)
}

// async/await - coroutine com resultado
val deferred: Deferred<Usuario> = scope.async {
    buscarUsuario(1)
}
val usuario = deferred.await()

// Execução paralela com async
suspend fun carregarDashboard(): Dashboard = coroutineScope {
    val usuario = async { buscarUsuario(1) }
    val pedidos = async { buscarPedidos(1) }
    val notificacoes = async { buscarNotificacoes(1) }

    Dashboard(
        usuario = usuario.await(),
        pedidos = pedidos.await(),
        notificacoes = notificacoes.await()
    )
}

// runBlocking - ponte entre código síncrono e suspense
fun main() = runBlocking {
    val resultado = buscarUsuario(1)
    println(resultado)
}

// Dispatchers
// Dispatchers.Main      -> thread principal (Android UI)
// Dispatchers.IO        -> operações de I/O (rede, disco)
// Dispatchers.Default   -> operações CPU-intensive

// Flow - streams assíncronos reativos
fun contagem(): Flow<Int> = flow {
    for (i in 1..10) {
        delay(100)
        emit(i)
    }
}

// Coletando e transformando Flows
suspend fun exemploFlow() {
    contagem()
        .filter { it % 2 == 0 }
        .map { it * it }
        .collect { valor ->
            println("Recebido: $valor")
        }
}

// StateFlow e SharedFlow (para estado reativo)
class MeuViewModel : ViewModel() {
    private val _estado = MutableStateFlow<Estado>(Estado.Carregando)
    val estado: StateFlow<Estado> = _estado.asStateFlow()

    fun carregar() {
        viewModelScope.launch {
            _estado.value = Estado.Sucesso(buscarDados())
        }
    }
}

Consulte também os termos Flow, Dispatcher, suspend e launch no glossário.


10. Estruturas de Dados

Kotlin facilita a criação de estruturas leves com destructuring e type aliases.

// Pair e Triple
val coordenada = Pair(10.0, 20.0)    // ou: 10.0 to 20.0
val (x, y) = coordenada

val rgb = Triple(255, 128, 0)
val (r, g, b) = rgb

// Data classes como DTOs
data class EnderecoDTO(
    val rua: String,
    val cidade: String,
    val estado: String,
    val cep: String
)

// Destructuring em data classes
val endereco = EnderecoDTO("Av. Paulista", "São Paulo", "SP", "01310-100")
val (rua, cidade, _, cep) = endereco  // _ ignora componente

// Sealed class como hierarquia de estados
sealed class NetworkResult<out T> {
    data class Success<T>(val data: T) : NetworkResult<T>()
    data class Error(val code: Int, val message: String) : NetworkResult<Nothing>()
    object Loading : NetworkResult<Nothing>()
}

fun <T> NetworkResult<T>.getOrNull(): T? = when (this) {
    is NetworkResult.Success -> data
    is NetworkResult.Error -> null
    NetworkResult.Loading -> null
}

// Type aliases - nomes descritivos para tipos complexos
typealias UserId = Long
typealias Handler<T> = suspend (T) -> Unit
typealias UserCache = MutableMap<UserId, Usuario>

fun buscar(id: UserId): Usuario? = cache[id]

// Map de destructuring
val mapa = mapOf("nome" to "Ana", "cidade" to "SP")
for ((chave, valor) in mapa) {
    println("$chave = $valor")
}

11. Comandos Úteis

Referência rápida para compilação, execução e ferramentas do ecossistema Kotlin. Veja nosso guia de Gradle para configuração completa.

// Terminal: compilar e executar
// kotlinc Main.kt -include-runtime -d app.jar
// java -jar app.jar

// Gradle (Kotlin DSL) - comandos essenciais
// gradle build          -> compila o projeto
// gradle run            -> executa a aplicação
// gradle test           -> roda os testes
// gradle clean build    -> limpa e recompila
// gradle dependencies   -> lista dependências

// build.gradle.kts (Gradle Kotlin DSL)
plugins {
    kotlin("jvm") version "2.1.0"
    application
}

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
    testImplementation(kotlin("test"))
    testImplementation("io.mockk:mockk:1.13.13")
}

application {
    mainClass.set("com.exemplo.MainKt")
}

tasks.test {
    useJUnitPlatform()
}

// Kotlin Scripts (.kts) - execute diretamente
// kotlinc -script meu_script.main.kts

// Arquivo: meu_script.main.kts
@file:DependsOn("com.squareup.okhttp3:okhttp:4.12.0")
import okhttp3.OkHttpClient
import okhttp3.Request

val client = OkHttpClient()
val response = client.newCall(
    Request.Builder().url("https://api.exemplo.com/dados").build()
).execute()
println(response.body?.string())

Confira nosso guia de CI/CD com Kotlin e o post sobre GitHub Actions.


12. Dicas e Truques

Recursos avançados que tornam Kotlin expressivo e produtivo. Veja o glossário de DSL, inline e reified.

// Scope functions - quando usar cada uma
// let   -> transformar nullable, encadear operações
// run   -> executar bloco no contexto do objeto, retorna resultado
// with  -> agrupar chamadas no mesmo objeto (non-null)
// apply -> configurar objeto, retorna o próprio objeto
// also  -> ações laterais (log, validação), retorna o próprio objeto

val resultado = usuario?.let { u ->
    "Bem-vindo, ${u.nome}"
} ?: "Visitante"

val conexao = DatabaseConfig().apply {
    url = "jdbc:postgresql://localhost:5432/meudb"
    usuario = "admin"
    maxPool = 10
}.also {
    println("Config criada: ${it.url}")
}

val relatorio = with(estatisticas) {
    """
    Total: $total
    Média: $media
    Máximo: $maximo
    """.trimIndent()
}

// Delegation com by
class MeuRepositorio(
    private val cache: MutableMap<String, String> = mutableMapOf()
) : MutableMap<String, String> by cache {
    override fun put(key: String, value: String): String? {
        println("Inserindo: $key -> $value")
        return cache.put(key, value)
    }
}

// Property delegation
class Preferencias {
    var tema: String by Delegates.observable("claro") { _, antigo, novo ->
        println("Tema mudou de $antigo para $novo")
    }
    var fontSize: Int by Delegates.vetoable(14) { _, _, novo ->
        novo in 8..72  // rejeita valores fora do intervalo
    }
}

// Inline functions com reified type parameters
inline fun <reified T> String.parseJson(): T {
    return Json.decodeFromString<T>(this)  // tipo T disponível em runtime
}

val usuario = """{"nome":"Ana"}""".parseJson<Usuario>()

// Verificação de tipo com reified
inline fun <reified T> List<Any>.filterByType(): List<T> {
    return filterIsInstance<T>()
}

val strings = listOf(1, "dois", 3, "quatro").filterByType<String>()

// DSL Builder - criando APIs expressivas
class HtmlBuilder {
    private val elements = mutableListOf<String>()

    fun h1(texto: String) { elements.add("<h1>$texto</h1>") }
    fun p(texto: String) { elements.add("<p>$texto</p>") }
    fun ul(bloco: UlBuilder.() -> Unit) {
        val ul = UlBuilder().apply(bloco)
        elements.add(ul.build())
    }

    fun build(): String = elements.joinToString("\n")
}

class UlBuilder {
    private val items = mutableListOf<String>()
    fun li(texto: String) { items.add("  <li>$texto</li>") }
    fun build(): String = "<ul>\n${items.joinToString("\n")}\n</ul>"
}

fun html(bloco: HtmlBuilder.() -> Unit): String =
    HtmlBuilder().apply(bloco).build()

// Uso do DSL
val pagina = html {
    h1("Meu Site")
    p("Bem-vindo ao Kotlin Brasil!")
    ul {
        li("Coroutines")
        li("Flow")
        li("Compose")
    }
}

Leia mais sobre programação funcional em Kotlin e DSLs em Kotlin nos nossos conteúdos.


Próximos Passos

Explore outros ecossistemas em português: Se você trabalha com microserviços, conheça Go em golang.com.br – uma linguagem excelente para serviços de alta performance. Para programação de sistemas e segurança de memória, veja Rust em rustlang.com.br. E para data science, automação e scripts rápidos, confira Python em python.dev.br.