Um switch compara um valor com uma lista de cases e executa o primeiro que casar. Diferente de C, Java e JavaScript, um case em Go não cai no próximo (não há fall through), então não existe break para esquecer.
Os cases são verificados de cima para baixo, e só o primeiro que casar é executado. default executa quando nada casa; ele é opcional e pode aparecer em qualquer posição da lista, embora por convenção fique por último.
Vários valores por case
case "sat", "sun": casa com qualquer um dos dois valores. É assim que Go expressa o que C faz com cases vazios empilhados. Qualquer tipo comparável funciona: strings, números, runes, booleanos, ponteiros e tipos nomeados como enums:
Dois cases com o mesmo valor constante são erro de compilação:
./main.go:10:7: duplicate case 1 (constant of type int) in expression switch
./main.go:8:7: previous case
switch sem condição
Deixe a expressão de fora e cada case vira um teste booleano. Essa é a forma mais limpa que Go tem de escrever uma cadeia longa de if/else if:
switch { é um atalho para switch true {. Como o primeiro case verdadeiro vence, a ordem importa: bmi < 25 só é alcançado quando bmi < 18.5 foi falso, então cada case pode assumir que os de cima falharam.
switch com instrução de inicialização
Como o if, um switch pode começar com uma instrução curta. As variáveis declaradas ali têm o escopo do switch:
A instrução de inicialização também pode ser combinada com um switch sem expressão: switch n := len(items); { case n == 0: ... }.
fallthrough
Quando você quer mesmo continuar no próximo case, escreva fallthrough como última instrução de um case. Ele passa o controle para o corpo do próximo case sem avaliar a condição dele:
O nível 2 imprime write e depois read, acumulando permissões para baixo. As condições dos cases seguintes não são verificadas: depois do fallthrough a partir do case 2, o case 1 executa mesmo com level valendo 2.
Regras do fallthrough:
- Precisa ser a última instrução do case.
- Não pode aparecer no último case:
cannot fallthrough final case in switch. - Não é permitido em um type switch.
Na prática, fallthrough é raro em código Go. Vários valores por case resolvem a necessidade comum, e chamadas explícitas de função costumam ser mais claras que uma cadeia de fallthroughs.
break em um switch
break dentro de um case sai do switch. Os cases terminam sozinhos, então você só precisa dele para sair mais cedo de um case. A armadilha é um switch dentro de um laço:
Sem o label loop, o break encerra o switch e o laço segue para "c". Já o continue sempre se refere ao laço que envolve o switch, já que um switch não é um laço.
switch sobre tipos
Um type switch ramifica pelo tipo dinâmico de um valor de interface, usando a forma especial v.(type):
Em um case com um único tipo, x tem esse tipo (len(x) funciona no case string). Em um case que lista vários tipos, x mantém o tipo da interface. A página de type assertions cobre type switches e a assertion v.(T) em detalhes.
O que o switch do Go faz diferente
| Comportamento | C, Java, JavaScript | Go |
|---|---|---|
| Cair no próximo case | padrão | só com fallthrough |
break no fim de cada case | obrigatório | desnecessário |
| Vários valores por case | cases vazios empilhados | case a, b, c: |
| Valores dos cases | constantes (na maioria) | qualquer expressão, avaliada de cima para baixo |
| Valor do switch | tipos inteiros (C) | qualquer tipo comparável |
| Sem expressão no switch | não permitido | switch { case cond: } |
As expressões dos cases não precisam ser constantes. case limit(), max + 1: é válido; elas são avaliadas em ordem até uma casar, então as expressões seguintes podem nunca ser executadas.
Exaustividade
Go não verifica se um switch sobre um enum cobre todos os valores. Acrescente um default que registra em log, devolve um erro ou causa panic para valores que você não esperava, ou use o linter exhaustive (parte do golangci-lint) para que cases faltando sejam reportados no build.
Perguntas frequentes
O switch do Go cai no próximo case?
Não. Um case em Go termina automaticamente no próximo case; você nunca escreve break para pará-lo. Se quiser que a execução continue no corpo do próximo case, escreva fallthrough como última instrução do case. Ele salta incondicionalmente, sem verificar a condição do próximo case.
Como casar vários valores em um só case em Go?
Liste os valores separados por vírgula: case "sat", "sun":. O case executa se o valor do switch for igual a qualquer um deles. Isso substitui os cases vazios empilhados que você usaria em C ou Java.
O que é um switch sem condição em Go?
switch { case x < 0: ...; case x == 0: ...; default: ... }. Sem expressão depois do switch, cada case é uma condição booleana e o primeiro verdadeiro é executado. É o substituto idiomático para uma cadeia longa de if/else if.
O que o break faz dentro de um switch em Go?
Ele encerra o switch, não um laço for ao redor. Isso raramente é necessário, já que os cases terminam sozinhos, mas surpreende quem escreve break em um switch dentro de um laço esperando sair do laço. Use um break com label ou return para isso.