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
- Aprofunde-se com o Guia Completo de Kotlin
- Aprenda Coroutines em detalhes
- Explore Kotlin para Backend com Spring ou Ktor
- Confira nosso Guia de Testes com Kotlin
- Prepare-se para entrevistas com as perguntas mais comuns sobre Kotlin
- Veja o Glossário Kotlin completo para todos os termos
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.