Skip to content

Pattern Matching

Pattern matching permite inspecionar a estrutura de um valor e executar código baseado em qual padrão ele satisfaz.


match é uma expressão — retorna um valor. Todo arm deve retornar o mesmo tipo:

val descricao = match codigo {
200 => "OK"
404 => "Não encontrado"
500 => "Erro interno"
_ => "Desconhecido"
}

O resultado pode ser usado diretamente:

print(match status {
true => "ativo"
false => "inativo"
})

match n {
0 => "zero"
1 => "um"
3.14 => "pi"
"oi" => "saudação"
true => "verdadeiro"
_ => "outro"
}

Captura o valor em uma variável:

match valor {
x => "o valor é $(x)" // x recebe o valor
}

_ ignora o valor sem capturá-lo:

match resultado {
Ok(v) => usar(v)
_ => ignorar()
}
match resultado {
Ok(dados) => processar(dados)
Err(e) => log(e.message())
}
match opcao {
Some(v) => usar(v)
None => padrao()
}

Desestrutura os campos de um record:

match ponto {
Ponto { x, y } => "X: $(x), Y: $(y)"
}
match par {
(0, 0) => "origem"
(x, y) => "$(x), $(y)"
}

Adiciona uma condição extra com if ou when:

match n {
x if x < 0 => "negativo"
x if x == 0 => "zero"
x => "positivo"
}

O compilador garante que o match seja exaustivo. Se você não cobrir todos os casos (ou usar um wildcard _), receberá um erro de compilação.


Arms podem ter blocos para lógica mais complexa:

val resultado = match operacao {
Somar(a, b) => {
val r = a + b
return r
}
}

Pattern matching em parâmetros de função

Section titled “Pattern matching em parâmetros de função”

Em Soyuz, o pattern matching em parâmetros de função é realizado através de sobrecarga com a keyword when.

fn fatorial(n: Int) when n == 0 = 1
fn fatorial(n: Int) = n * fatorial(n - 1)
  1. Variante Catch-all: Você deve sempre fornecer uma variante sem a cláusula when para garantir que a função seja exaustiva.
  2. Ordem: O compilador tenta casar os padrões na ordem em que as funções foram declaradas.

fn fib(n: Int) when n == 0 = 0
fn fib(n: Int) when n == 1 = 1
fn fib(n: Int) = fib(n - 1) + fib(n - 2)
fn processar(r: Result[Int]) {
match r {
Ok(v) => print("Sucesso: $(v)")
Err(e) => print("Erro: $(e.message())")
}
}