func total(prices: Int[]): Int {
mut sum := 0
for each p in prices {
sum += p
}
return sum
}
proc main(): void {
assert total([3, 4]) == 7 // vale: nada acontece
echo "o carrinho fecha a conta"
assert total([3, 4]) == 8 // não vale: o programa para, aqui
echo "nunca alcançado"
}$ hive run basket.hive
o carrinho fecha a conta
panic: hive: assertion failed: total([3, 4]) == 8
left: 7
right: 8
goroutine 1 [running]:
…func sign(n: Int): Int {
if n > 0 {
return 1
} else if n < 0 {
return -1
} else if n == 0 {
return 0
}
// Todo Int é um dos três, mas nada prova isso ao compilador.
panic "um Int que não é positivo, negativo nem zero: {n}"
}
proc main(): void {
echo sign(-8)
}assert cond diz: isto precisa valer. O que acontece quando não vale é decidido por onde está escrito. Em código comum, uma asserção que falha provou que o programa está errado, então o programa para, imprimindo a condição como foi escrita e, para == ou !=, no que cada lado deu. Dentro de um test, ela provou que o teste está errado, então a falha é registrada e o resto da suíte continua rodando — o slide de testes mostra esse relatório. De qualquer forma, seus operandos são avaliados exatamente uma vez, valendo ou não.
panic value para o programa na hora, imprimindo value do jeito que o echo faria — então um átomo imprime seu nome — e aceita qualquer valor, não só um Bool. Ele nunca retorna, então um caminho que termina em panic conta como encerrado, que é o que fecha um final que o verificador não consegue ver que é inalcançável. Um assert não: um que vale segue adiante. Um panic dentro de um teste reprova só aquele teste, e um dentro de um serviço mata só aquele serviço.