If/Else
Conditional branching with if, else if, and else - including the idiomatic init-statement form used for error checks.
Go's if statement works like most languages, with two additions: conditions do not need parentheses, and the if statement can include a short initialiser before the condition.
A simple if/else if/else chain. The condition must be a boolean expression - no implicit truthiness.
package main
import "fmt"
func main() {
x := 7
if x > 10 {
fmt.Println("big")
} else if x > 4 {
fmt.Println("medium")
} else {
fmt.Println("small")
}
// medium
}The init-statement form runs a short statement before evaluating the condition. The variable declared in the init is scoped to the entire if/else block - it does not leak into the surrounding scope.
package main
import (
"fmt"
"strconv"
)
func main() {
if n, err := strconv.Atoi("42"); err == nil {
fmt.Println("parsed:", n)
} else {
fmt.Println("error:", err)
}
// parsed: 42
// n and err are not accessible here
}The init-statement form is most common with error checks: run the operation, capture the error, and handle it - all in one line. The variable declared in the init is not accessible outside the block.
package main
import (
"fmt"
"os"
)
func main() {
if f, err := os.Open("data.txt"); err != nil {
fmt.Println("cannot open:", err)
} else {
defer f.Close()
fmt.Println("opened:", f.Name())
}
}In production
The if err != nil { return err } pattern is idiomatic Go error handling - not a limitation, but a deliberate design choice that makes error paths explicit at every call site. Avoid nesting multiple init-statement if blocks in sequence; a long chain of if x, err := ...; err != nil { ... } blocks is harder to follow than extracting the logic into a named function that returns early. Each early return is a documented exit point - that is the intent.
Enjoyed this? Get more essays on software craft delivered to your inbox.
Subscribe free