Menu

if else em Golang: sintaxe, instrução de inicialização e if err != nil

Como if, else if e else funcionam em Go: sem parênteses, chaves obrigatórias, o if com cláusula de inicialização e o seu escopo, o idioma if err != nil e retornos antecipados em vez de aninhamento profundo.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

O if do Go não tem parênteses em volta da condição, sempre exige chaves e pode começar com uma instrução curta que declara variáveis com escopo restrito ao if.

As condições são avaliadas de cima para baixo e o primeiro ramo verdadeiro é executado. else if e else são opcionais.

Regras de sintaxe

Três regras diferem de C, Java e JavaScript:

  1. Sem parênteses em volta da condição. if (x > 5) compila, mas o gofmt remove os parênteses.
  2. Chaves são obrigatórias, mesmo para uma única instrução. Não existe if x > 5 return sem chaves.
  3. O else fica na mesma linha da chave de fechamento. Go insere um ponto e vírgula depois de uma } no fim da linha, então isto falha:
if x > 5 {
	fmt.Println("big")
}
else {
	fmt.Println("small")
}
syntax error: unexpected keyword else, expected }

Escreva } else { em uma linha só.

A condição precisa ser um bool. Go não trata 0, "" ou nil como falso, então if count {} e if name {} não compilam. Compare de forma explícita: if count > 0, if name != "", if user != nil.

Combine condições com && (e), || (ou) e ! (não). && e || fazem curto-circuito, o que torna as verificações de nil seguras:

if user != nil && user.IsAdmin() {
	// user.IsAdmin() is only called when user is not nil
}

if com instrução de inicialização

Um if pode executar uma instrução curta antes da condição, separada por ponto e vírgula. As variáveis declaradas nela ficam visíveis em todos os ramos daquele if, e em nenhum lugar depois:

O padrão mantém variáveis de vida curta fora do escopo ao redor. Ele aparece o tempo todo com buscas em map (v, ok := m[k]), type assertions (s, ok := v.(string)) e erros.

O outro lado: se você precisa do valor depois do if, declare-o antes. Um erro comum é colocar um resultado na instrução de inicialização e depois tentar usá-lo mais abaixo.

O idioma if err != nil

Funções que podem falhar devolvem um error por último. Verifique na hora, trate ou devolva o erro e siga com o caminho feliz sem indentação:

Repare que não há else depois de if err != nil { return ... }. O estilo Go trata o erro, retorna e deixa o fluxo normal na margem esquerda. A página de tratamento de erros cobre o empacotamento e a verificação de tipos de erro.

Retornos antecipados em vez de aninhamento

Blocos if muito aninhados são difíceis de ler. Inverta as condições e retorne cedo; cada verificação passa a funcionar como uma guarda:

// Nested
func canCheckout(u *User, cart *Cart) bool {
	if u != nil {
		if u.Verified {
			if len(cart.Items) > 0 {
				return true
			}
		}
	}
	return false
}

// Guards
func canCheckout(u *User, cart *Cart) bool {
	if u == nil || !u.Verified {
		return false
	}
	if len(cart.Items) == 0 {
		return false
	}
	return true
}

Programadores Go chamam isso de manter o caminho feliz alinhado à esquerda. Linters como o revive apontam um else depois de um bloco que termina em return, porque o else acrescenta indentação sem motivo.

if/else ou switch

Uma cadeia longa de else if que testa um valor contra vários casos fica mais legível como switch. Um switch sem expressão substitui uma cadeia if/else if de condições quaisquer:

switch {
case score >= 90:
	return "A"
case score >= 80:
	return "B"
default:
	return "F"
}

Use if para um ou dois ramos, e switch a partir de três.

Sem operador ternário

Go não tem cond ? a : b. Atribua com if:

label := "odd"
if n%2 == 0 {
	label = "even"
}

A página do operador ternário explica o porquê e mostra as alternativas.

Erros comuns

  • Shadowing com :=. if x, err := f(); err == nil { ... } declara um x novo só para o if. Um x de fora não é atualizado.
  • Atribuição na condição. if x = 5 {} é erro de compilação (cannot use assignment x = 5 as value), e não um bug silencioso como em C. Use ==.
  • Comparar floats com ==. if total == 0.3 falha para valores calculados. Compare com uma tolerância.
  • Verificar o erro errado. Depois de a, err := f() e b, err := g(), confira se cada if err != nil está logo depois da sua chamada.

Perguntas frequentes

Como escrever if else em Go?

Sem parênteses em volta da condição, e com chaves sempre obrigatórias:

if x > 10 {
	fmt.Println("big")
} else if x > 5 {
	fmt.Println("medium")
} else {
	fmt.Println("small")
}

O else precisa ficar na mesma linha da chave de fechamento do bloco anterior.

O que é um if com instrução de inicialização em Go?

Uma instrução curta antes da condição, separada por ponto e vírgula: if n, err := strconv.Atoi(s); err != nil { ... }. As variáveis declaradas ali só existem dentro do if e dos seus ramos else if e else, o que evita que vazem para o resto da função.

Dá para escrever um if em uma linha em Go?

Não sem chaves. if ok return e if (ok) x = 1; são erros de sintaxe. A forma mais curta é if ok { return }, e o gofmt coloca o corpo em uma linha própria. Go também não tem operador ternário, então um valor condicional exige um if/else ou uma pequena função auxiliar.

Por que Go usa if err != nil em todo lugar?

Go não tem exceções. Funções que podem falhar devolvem um error como último resultado, e quem chama verifica na hora com if err != nil. A repetição é o preço de ter cada ponto de falha visível onde acontece.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR