Pular para o conteúdo

O livro · 02

Funções e fluxo

book.md · 96 linhas · 2 min de leitura

Objetivo: escrever funções, entender por que nada é retornado por posição, e usar os dois construtos unificados de controle: match e loop.

fn add(a: int, b: int) -> int {
return a + b
}
fn saudar(nome: string) { // sem '->': não devolve valor (não há 'void')
io.println("oi, {{nome}}")
}
pub fn dobro(x: int) -> int { return x * 2 } // 'pub' = visível a outros módulos

Parâmetros com default e variádicos:

fn conectar(host: string, porta: u16 = 8080) { ... } // 'porta' tem default
fn somar(xs: ...int) -> int { ... } // variádico: '...' prefixo

Um bloco não vale a sua última expressão. Toda saída é marcada explicitamente: por return, pelo ?: do ternário, ou pelo => de um lambda. O proibido é entregar por posição (“a última linha é o valor”). Marcar por glifo curto conta como explícito; só não se adivinha.

fn maior(a: int, b: int) -> int {
return a > b ? a : b // ternário: escolha entre DOIS valores
}

O return distribui sobre match/if em posição de valor:

fn classificar(n: int) -> string {
return match { // 'return <match>' distribui o return pros braços
n < 0 => "negativo"
n == 0 => "zero"
_ => "positivo"
}
}

Um construto só para “dado X, escolha um galho”, que absorve switch, match clássico e select. O token logo após match decide a forma:

// com sujeito → casa padrões / valores
match status {
200 | 201 | 204 => ok() // or-pattern com '|' (cobre o fallthrough)
404 => sumiu()
_ => outro() // domínio aberto (int) → exige '_'
}

Exaustividade é levada a sério: em domínio fechado (enum, error-set) o compilador exige todos os galhos e proíbe _. Adicionar uma variante quebra a build até você tratá-la. Em domínio aberto (int, string) o _ é obrigatório.

(A forma match { ... } sem sujeito é o select de channels, no capítulo 06.)

for, while e loop infinito diferem só no cabeçalho, então há uma keyword, loop:

loop { break } // sem cabeçalho → infinito
loop ativo { ... } // expressão booleana → while
loop item in lista { ... } // IDENT in iterável → for-each
loop i in 0..8 { ... } // range exclusivo (..= é inclusivo)
loop i := 0; i < 8; i = i + 1 { } // C-style; ';' delimita as 3 partes

break e continue funcionam igual em todas as formas.

Função anônima passada inline. Duas formas, ambas só em posição de argumento (não se liga a um nome; pra reusar, dê um nome com fn):

nums.filter(fn(x) => x > 0) // forma curta: '=>' entrega o valor
nums.map(fn(x) { y := x * 2; return y }) // forma de corpo: 'return' explícito

Próximo: 03 · Tipos compostos