Kotlin: Sintaxe Básica do Kotlin Explicada

Última atualização: 2026-08-26

A filosofia de sintaxe do Kotlin: use expressões em vez de instruções sempre que possível, e nunca escreva uma linha que não precise. Isso permite que Alice escreva código 40% mais curto que Java, expressando mais.

1. O que Você Aprenderá


2. A História Real de um Desenvolvedor

(1) Problema: Estado Mutável Causa Bugs de Concorrência

Alice usou var para definir um contador de pedidos compartilhado no OrderProcessor. Sob alta concorrência, corridas de dados causaram um desvio de contagem de 2% — são 20.000 pedidos mal contados em escala.

(2) Solução: Imutabilidade em Primeiro Lugar

KOTLIN
// RUIM: estado compartilhado mutável
var orderCount = 0  // Condição de corrida!

// BOM: imutável + pipeline funcional
val processedOrders = orders
    .filter { it.status == "CONFIRMED" }
    .also { println("Processados ${it.size} pedidos") }

Dados imutáveis são naturalmente seguros para threads. val é a primeira escolha de todo desenvolvedor Kotlin; var é o último recurso.


3. val vs var: Imutabilidade em Primeiro Lugar

(1) Sintaxe Básica

KOTLIN
// val: somente leitura (referência imutável) - PREFERIDO
val orderId = "ORD-001"         // Tipo inferido como String
val total: Double = 299.99      // Tipo explícito

// var: mutável (reatribuível) - USE COM CUIDADO
var status = "PENDING"          // Pode ser reatribuído
status = "CONFIRMED"            // OK

// val NÃO significa que o objeto é imutável
val items = mutableListOf<Order>()  // Referência é val, lista é mutável
items.add(Order("ORD-002", 150.0, "NEW"))  // OK - modificando a lista
// items = mutableListOf()  // ERRO - não pode reatribuir val

(2) Comparação val vs var

Dimensão val var
Reatribuível Não Sim
Segurança de thread Referência imutável, naturalmente segura Precisa de sincronização
Recomendação Preferido Último recurso
Análogo Java final Variável regular
Por baixo dos panos Referência somente leitura (objeto pode ser mutável) Referência mutável

4. Templates de String

(1) Templates Básicos

KOTLIN
val orderId = "ORD-001"
val total = 299.99

// Referência simples de variável
println("Pedido: $orderId")

// Expressão no template
println("Total: \$$total USD")
println("Imposto: \$${total * 0.08} USD")

// Expressão arbitrária com ${}
val items = listOf("Widget", "Gadget")
println("Quantidade de itens: ${items.size}, Primeiro: ${items[0]}")

(2) Strings Brutas (Multilinha)

KOTLIN
val receipt = """
    |ID Pedido: ORD-001
    |Total: $299.99 USD
    |Status: CONFIRMED
""".trimMargin()

// Alternativa: trimIndent
val json = """
    {
      "order_id": "ORD-001",
      "total": 299.99
    }
""".trimIndent()

(3) Comparação de Templates de String

Recurso Java Kotlin
Referência de variável "Order " + id "Order $id"
Expressão "Tax: " + (t * 0.08) "Tax: ${t * 0.08}"
Multilinha Sem suporte nativo """ ... """
Tratamento de indentação Manual trimMargin() / trimIndent()

5. Expressão when

when é a atualização completa do switch — é uma expressão com valor de retorno que pode corresponder a tipos, intervalos e condições arbitrárias.

(1) Uso Básico

KOTLIN
// when como expressão (deve ser exaustivo)
val status = "CONFIRMED"
val label = when (status) {
    "PENDING" -> "Aguardando pagamento"
    "CONFIRMED" -> "Pagamento recebido"
    "SHIPPED" -> "Em trânsito"
    "CANCELLED" -> "Pedido cancelado"
    else -> "Status desconhecido"
}

(2) Correspondência Avançada

KOTLIN
// Múltiplos valores
when (status) {
    "PENDING", "NEW" -> processNewOrder()
    in listOf("CONFIRMED", "PAID") -> shipOrder()
    else -> handleOther()
}

// Correspondência por intervalo
val quantity = 150
when (quantity) {
    in 1..10 -> println("Pedido pequeno")
    in 11..100 -> println("Pedido médio")
    in 101..1_000 -> println("Pedido grande")
    else -> println("Pedido em volume")
}

// Correspondência por tipo
fun describe(obj: Any): String = when (obj) {
    is String -> "String de comprimento ${obj.length}"
    is Int -> "Inteiro: $obj"
    is List<*> -> "Lista com ${obj.size} elementos"
    else -> "Tipo desconhecido"
}

(3) Árvore de Decisão do when

100%
flowchart LR
    A[when status] --> B["PENDING, NEW"]
    A --> C["CONFIRMED, PAID"]
    A --> D["SHIPPED"]
    A --> E["CANCELLED"]
    A --> F[else]
    B --> B1[processNewOrder]
    C --> C1[shipOrder]
    D --> D1[trackShipment]
    E --> E1[refundOrder]
    F --> F1[handleOther]

(4) when vs switch

Dimensão Java switch Kotlin when
Valor de retorno Instrução, sem retorno Expressão, retorna valor
Correspondência de múltiplos valores Requer fall-through "A", "B" separados por vírgula
Correspondência por intervalo Não disponível in 1..100
Correspondência por tipo Não disponível is String
Condição de guarda Não disponível x > 0 arbitrária
Verificação de exaustividade Nenhuma Aplicada pelo compilador (modo expressão)

6. Intervalos e Iteração

(1) Operadores de Intervalo

KOTLIN
// Intervalo fechado: inclui ambos os extremos
for (i in 1..5) print("$i ")  // 1 2 3 4 5

// Intervalo semiaberto: exclui o final
for (i in 1 until 5) print("$i ")  // 1 2 3 4

// Passo
for (i in 1..10 step 2) print("$i ")  // 1 3 5 7 9

// Decrescente
for (i in 5 downTo 1) print("$i ")  // 5 4 3 2 1

// Intervalo de caracteres
for (c in 'A'..'E') print("$c ")  // A B C D E

(2) Iteração de Coleções

KOTLIN
val orders = listOf(
    Order("ORD-001", 299.99),
    Order("ORD-002", 1_500.00),
    Order("ORD-003", 45.50)
)

// Iterar com índice
for ((index, order) in orders.withIndex()) {
    println("[$index] ${order.id}: \$${order.total} USD")
}

// Iterar mapa
val statusMap = mapOf("ORD-001" to "SHIPPED", "ORD-002" to "PENDING")
for ((id, status) in statusMap) {
    println("$id -> $status")
}

(3) Referência Rápida de Operadores de Intervalo

Operador Significado Exemplo Resultado
.. Intervalo fechado 1..5 1,2,3,4,5
until Intervalo semiaberto 1 until 5 1,2,3,4
step Tamanho do passo 1..10 step 3 1,4,7,10
downTo Decrescente 5 downTo 1 5,4,3,2,1
in Verificação de pertencimento 3 in 1..5 true

7. Funções de Corpo de Expressão e Idiomas

(1) Funções de Corpo de Expressão

KOTLIN
// Corpo de bloco
fun calculateTax(total: Double): Double {
    return total * 0.08
}

// Corpo de expressão (mais conciso)
fun calculateTax(total: Double): Double = total * 0.08

// Inferência de tipo com corpo de expressão
fun calculateTax(total: Double) = total * 0.08

(2) Idiomas Kotlin

KOTLIN
// 1. Ponto e vírgula é opcional
val x = 1  // Sem ponto e vírgula necessário

// 2. Convenção de lambda final
orders.filter { it.total > 1_000 }  // lambda fora dos parênteses

// 3. Palavra-chave it para lambda de parâmetro único
orders.map { it.id }  // 'it' = parâmetro implícito

// 4. Template de string em vez de concatenação
val msg = "Pedido $orderId confirmado"  // Não "Pedido " + orderId + " confirmado"

// 5. Corpo de expressão para funções simples
fun isHighValue(order: Order) = order.total > 10_000

(3) Comparação de Idiomas: Java vs Kotlin

Idioma Java Kotlin
Ponto e vírgula Obrigatório Opcional
Concatenação de string Operador + Template $
Funções simples Corpo de bloco Corpo de expressão
Posicionamento de lambda Dentro dos parênteses Final, fora dos parênteses
Lambda de parâmetro único Parâmetro nomeado Palavra-chave it

8. Exemplo Completo: Roteamento de Pedidos do OrderProcessor

KOTLIN
// ============================================
// OrderProcessor - Motor de Roteamento de Pedidos
// Funcionalidade: Rotear pedidos com base em status e valor
// ============================================

data class Order(val id: String, val total: Double, val status: String)

fun routeOrder(order: Order): String = when {
    order.status == "CANCELLED" -> "REFUND_QUEUE"
    order.total > 10_000 -> "VIP_PIPELINE"
    order.total > 1_000 -> "PRIORITY_PIPELINE"
    order.status == "CONFIRMED" -> "STANDARD_PIPELINE"
    order.status in listOf("PENDING", "NEW") -> "WAITING_QUEUE"
    else -> "MANUAL_REVIEW"
}

fun processBatch(orders: List<Order>) {
    for ((index, order) in orders.withIndex()) {
        val pipeline = routeOrder(order)
        val priority = when (pipeline) {
            "VIP_PIPELINE" -> "CRITICAL"
            "PRIORITY_PIPELINE" -> "HIGH"
            "STANDARD_PIPELINE" -> "NORMAL"
            else -> "LOW"
        }
        println("[${index + 1}] ${order.id} -> $pipeline (Prioridade: $priority)")
    }
}

fun main() {
    val orders = listOf(
        Order("ORD-001", 299.99, "CONFIRMED"),
        Order("ORD-002", 15_000.00, "CONFIRMED"),
        Order("ORD-003", 2_500.00, "PENDING"),
        Order("ORD-004", 45.50, "CANCELLED"),
        Order("ORD-005", 750.00, "NEW")
    )

    println("=== Relatório de Roteamento de Pedidos ===")
    processBatch(orders)

    // Resumo com pipeline funcional
    val pipelineCounts = orders
        .map { routeOrder(it) }
        .groupingBy { it }
        .eachCount()

    println("\n=== Distribuição por Pipeline ===")
    for ((pipeline, count) in pipelineCounts) {
        println("  $pipeline: $count pedidos")
    }
}

Saída:

TEXT 📖 Somente leitura
=== Relatório de Roteamento de Pedidos ===
[1] ORD-001 -> STANDARD_PIPELINE (Prioridade: NORMAL)
[2] ORD-002 -> VIP_PIPELINE (Prioridade: CRITICAL)
[3] ORD-003 -> PRIORITY_PIPELINE (Prioridade: HIGH)
[4] ORD-004 -> REFUND_QUEUE (Prioridade: LOW)
[5] ORD-005 -> WAITING_QUEUE (Prioridade: LOW)

=== Distribuição por Pipeline ===
  STANDARD_PIPELINE: 1 pedidos
  VIP_PIPELINE: 1 pedidos
  PRIORITY_PIPELINE: 1 pedidos
  REFUND_QUEUE: 1 pedidos
  WAITING_QUEUE: 1 pedidos

❓ Perguntas Frequentes

P: Posso modificar o conteúdo de uma coleção val? R: Sim. val apenas garante que a referência é imutável — o conteúdo da coleção ainda pode mudar. Para coleções verdadeiramente imutáveis, use listOf() em vez de mutableListOf().

P: when sempre requer else? R: Quando when é usado como expressão, o compilador exige exaustividade — você deve cobrir todos os ramos ou adicionar else. Quando usado como instrução, else é opcional.

P: 1..5 e 1 until 6 são iguais? R: Mesmo resultado, semântica diferente. 1..5 significa "de 1 até 5 inclusive", 1 until 6 significa "de 1 até (mas não incluindo) 6". Ao iterar índices de lista, until é mais comum.

P: Quando devo usar funções de corpo de expressão? R: Use corpos de expressão quando a função é uma única expressão. Use corpos de bloco para qualquer coisa com 2+ linhas de lógica. Legibilidade é a prioridade principal.

P: Qual a diferença entre $var e ${expr} nos templates de string? R: $var só pode referenciar nomes simples de variáveis; ${expr} pode conter qualquer expressão, como ${items.size} ou ${total * 0.08}.

P: when pode corresponder a intervalos de ponto flutuante? R: Tecnicamente sim, mas problemas de precisão de ponto flutuante podem causar resultados inesperados. Prefira intervalos inteiros ou comparações explícitas.


▶ Exemplo: val vs var

KOTLIN
val name = "Alice"  // imutável
var age = 30        // mutável
age = 31            // OK
// name = "Bob"     // erro de compilação

Saída:

TEXT 📖 Somente leitura
Compila; reatribuir name falha

▶ Exemplo: Expressão when

KOTLIN
val score = 85
val grade = when {
    score >= 90 -> "A"
    score >= 80 -> "B"
    else -> "C"
}
println(grade)

Saída:

TEXT 📖 Somente leitura
B

▶ Exemplo: Loop for

KOTLIN
for (i in 1..3) println(i)
for (s in listOf("a", "b")) println(s)

Saída:

TEXT 📖 Somente leitura
1
2
3
a
b

▶ Exemplo: Template de string multilinha

KOTLIN
val name = "Alice"
val orders = 1500
val revenue = 89500.50

val summary = """
    |== Relatório do Usuário ==
    |  Nome    : $name
    |  Pedidos : $orders
    |  Receita : \$${revenue} USD
    |  Média   : \$${revenue / orders} USD
    |================
""".trimMargin()
println(summary)

Saída:

TEXT 📖 Somente leitura
|== Relatório do Usuário ==
|  Nome    : Alice
|  Pedidos : 1500
|  Receita : $89500.5 USD
|  Média   : $59.66699999999999 USD
|================

▶ Exemplo: Intervalo com step e downTo

KOTLIN
// Intervalo crescente com step
for (i in 1..10 step 2) print("$i ")
println()

// Intervalo decrescente
for (i in 5 downTo 1) print("$i ")
println()

// Semiaberto com until
for (i in 0 until 5) print("$i ")

Saída:

TEXT 📖 Somente leitura
1 3 5 7 9
5 4 3 2 1
0 1 2 3 4

▶ Exemplo: Função de corpo de expressão

KOTLIN
// Corpo de bloco - múltiplas linhas
fun describeOrder(status: String): String {
    return when (status) {
        "CONFIRMED" -> "Confirmado"
        "SHIPPED" -> "Enviado"
        "DELIVERED" -> "Entregue"
        "CANCELLED" -> "Cancelado"
        else -> "Desconhecido"
    }
}

// Corpo de expressão - uma linha
fun isVip(total: Double) = total > 10_000

// Função sem valor de retorno (Unit)
fun logOrder(id: String): Unit = println("Registrado: $id")

println(describeOrder("CONFIRMED"))
println("VIP: ${isVip(15_000.0)}")
logOrder("ORD-001")

Saída:

TEXT 📖 Somente leitura
Confirmado
VIP: true
Registrado: ORD-001

▶ Exemplo: Null safety com when

KOTLIN
fun describeValue(v: Any?): String = when (v) {
    null -> "Valor nulo"
    is String -> "Texto com comprimento ${v.length}: \"$v\""
    is Int -> if (v > 0) "Inteiro positivo" else "Inteiro não positivo"
    is List<*> -> "Lista com ${v.size} elementos"
    is Map<*, *> -> "Mapa com ${v.size} entradas"
    else -> "Outro tipo: ${v::class.simpleName}"
}

println(describeValue(null))
println(describeValue("olá"))
println(describeValue(42))
println(describeValue(listOf(1, 2, 3)))
println(describeValue(3.14))

Saída:

TEXT 📖 Somente leitura
Valor nulo
Texto com comprimento 3: "olá"
Inteiro positivo
Lista com 3 elementos
Outro tipo: double

📖 Resumo


📝 Exercícios

  1. Iniciante (⭐) : Escreva uma função usando val e templates de string que produza um resumo de pedido "ORD-001: $299.99 USD (CONFIRMED)". Dica: val id = "ORD-001", val total = 299.99
  2. Intermediário (⭐⭐) : Implemente uma calculadora de desconto com when: > 10.000 → 20% de desconto, > 5.000 → 10% de desconto, caso contrário preço integral. Dica: condições de guarda when {}
  3. Desafio (⭐⭐⭐) : Implemente uma calculadora de imposto progressivo usando intervalos e when. Diferentes faixas de renda aplicam diferentes taxas de imposto. Dica: when { income in range -> ... }

← Anterior | Próximo →

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%