Fundamentos da Linguagem Kotlin

Kotlin é uma linguagem de programação estática e fortemente tipada, o que significa que os tipos das variáveis são verificados em tempo de compilação.

Tipos de Dados

Os tipos de dados numéricos básicos incluem Byte, Short, Int, Long, Float e Double. O tipo String represneta sequências de caracteres.

val mensagem: String = "Olá, mundo!"
val codigo: Int = 2023
val pi: Double = 3.14159
// Conversão de tipos
val inteiroParaDecimal = codigo.toFloat()
val decimalParaInteiro = pi.toInt()

Declaração de Variáveis

Utiliza-se val para referências imutáveis (similar ao final em Java) e var para referências mutáveis. É recomendável priorizar o uso de val.

val nomeSistema: String = "Alpha" // Imutável
var contador: Int = 0             // Mutável
contador = 1 // Válido
// nomeSistema = "Beta" // Erro de compilação

Segurança de Nulo

Por padrão, os tipos em Kotlin não aceitam valores nulos. Para permitir nulos, adiicona-se um sufixo ? ao tipo.

var nomeOpcional: String? = null
var nomeObrigatorio: String = "Inválido" // Não pode ser null

// Acesso seguro com operador ?.
val comprimento = nomeOpcional?.length // Retorna null se nomeOpcional for nulo

// Operador Elvis ?:
val valorSeguro = nomeOpcional ?: "Padrão"

Estruturas de Controle

if pode ser usado como expressão que retorna um valor. when é uma alternativa poderosa para múltiplas condições.

val resultado = if (x > y) x else y
when (objeto) {
    is String -> println("É uma string de comprimento ${objeto.length}")
    1, 2, 3 -> println("Valor pequeno")
    else -> println("Outro caso")
}

Loops for iteram sobre intervalos ou coleções.

for (item in lista) { /* ... */ }
for (indice in 0 until 10) { /* ... */ }

Funções

Funções são declaradas com a palavra-chave fun. Podem ter parâmetros com valores padrão.

fun calcularAreaComprimento(largura: Double, altura: Double = 2.0): Double {
    return largura * altura
}
// Chamada usando o valor padrão
val area = calcularAreaComprimento(5.0) // altura será 2.0

Funções de expressão única permitem sintaxe simplificada.

fun soma(a: Int, b: Int) = a + b

Funções de Alta Ordem e Lambda

Funções podem receber outras funções como parâmetros ou retorná-las. Lambda expressões são literais de função.

fun aplicarOperacao(x: Int, y: Int, operacao: (Int, Int) -> Int): Int {
    return operacao(x, y)
}
val somaLambda = { a: Int, b: Int -> a + b }
val total = aplicarOperacao(4, 5, somaLambda) // Resultado: 9
// Usando referência de função
fun multiplicar(a: Int, b: Int): Int = a * b
val produto = aplicarOperacao(3, 4, ::multiplicar)

Quando uma lambda é o último parâmetro, ela pode ser escrita fora dos parênteses (sintaxe trailing lambda).

aplicarOperacao(2, 3) { a, b -> a * b }

Programação Orientada a Objetos

Classes e Construtores

class Veiculo(val marca: String, var modelo: String) {
    var quilometragem: Double = 0.0
        private set

    fun dirigir(distancia: Double) {
        quilometragem += distancia
    }
}
// Instanciação
val meuCarro = Veiculo("Toyota", "Corolla")
meuCarro.dirigir(150.5)

Herança e Polimorfismo

Classes são final por padrão. Use open para permitir herança.

open class Forma(val nome: String) {
    open fun area(): Double = 0.0
}
class Circulo(val raio: Double) : Forma("Círculo") {
    override fun area() = Math.PI * raio * raio
}

Interfaces

interface Desenhavel {
    fun desenhar()
    fun preencher(cor: String) { // Implementação padrão
        println("Preenchendo com cor $cor")
    }
}
class Quadrado : Desenhavel {
    override fun desenhar() {
        println("Desenhando quadrado")
    }
}

Classes de Dados

Simplificam a criação de classes que servem principalmente para armazenar dados.

data class Ponto(val x: Double, val y: Double)
// Métodos equals(), hashCode(), toString(), copy() e componentN() gerados automaticamente

Objetos Companheiros

Substituem os membros estáticos de Java.

class Configuracao {
    companion object {
        const val VERSAO = "1.0"
        fun criarPadrao() = Configuracao()
    }
}
val config = Configuracao.criarPadrao()
val versao = Configuracao.VERSAO

Recursos Avançados

Funções de Extensão

Permitem adicionar funções a classes existentes sem modificá-las.

fun String.removerEspacosExcedentes(): String = this.trim().replace("  ", " ")
val texto = "  Olá   mundo  ".removerEspacosExcedentes() // "Olá mundo"

Delegação (by)

by lazy inicializa uma propriedade na primeira vez que é acessada, de forma thread-safe.

val bancoDeDados: Conexao by lazy {
    Conexao("jdbc:meubanco://localhost")
}
// Conexão estabelecida apenas na primeira chamada a bancoDeDados

Escopo de Classes Seladas

Limitam hierarquia a um conjunto fixo de subclasses, úteis com when.

sealed class ResultadoOperacao
class Sucesso(val dados: String) : ResultadoOperacao()
class Erro(val excecao: Exception) : ResultadoOperacao()

fun processarResultado(resultado: ResultadoOperacao) = when (resultado) {
    is Sucesso -> println("Dados: ${resultado.dados}")
    is Erro -> println("Erro: ${resultado.excecao.message}")
}

Null Safety Avançada

Use o operador !! com cautela, pois lança NullPointerException se o valor for nulo.

val textoNaoNulo: String = textoPotencialmenteNulo!!
// Assegura ao compilador que textoPotencialmenteNulo não é nulo (risco em runtime)

Tags: Kotlin linguagem-kotlin tipos-de-dados variaveis funções-kotlin

Publicado em 7-19 14:47