Conditional Control
Before You Start
- Applies to: Go 1.21+ (examples verified with Go 1.22) · Prerequisites: Variables · Read time: about 5 min
In Go, there are three conditional control statements: if, switch, and select. select is relatively special compared to the other two and will not be covered in this section. It will be explained in the concurrency chapter.
if else
if else has at most two branches. The syntax is as follows:
if expression {
}Or
if expression {
}else {
}expression must be a boolean expression, meaning the result must be either true or false, it must be a boolean value. Here are some examples:
func main() {
a, b := 1, 2
if a > b {
b++
} else {
a++
}
}You can also write more complex expressions. When necessary to improve readability, you should use parentheses to explicitly indicate which operations should be calculated first.
func main() {
a, b := 1, 2
if a<<1%100+3 > b*100/20+6 { // (a<<1%100)+3 > (b*100/20)+6
b++
} else {
a++
}
}At the same time, if statements can also contain some simple statements, for example:
func main() {
if x := 1 + 1; x > 2 {
fmt.Println(x)
}
}else if
else if statements can create more branches based on if else. The syntax is as follows:
if expression1 {
}else if expression2 {
}else if expression3 {
}else {
}During execution, each expression is evaluated from left to right, and the entire if statement is evaluated from top to bottom. An example of grading based on scores is as follows. The first approach:
func main() {
score := 90
var ans string
if score == 100 {
ans = "S"
} else if score >= 90 && score < 100 {
ans = "A"
} else if score >= 80 && score < 90 {
ans = "B"
} else if score >= 70 && score < 80 {
ans = "C"
} else if score >= 60 && score < 70 {
ans = "E"
} else if score >= 0 && score < 60 {
ans = "F"
} else {
ans = "nil"
}
fmt.Println(ans)
}The second method takes advantage of the premise that if statements are evaluated from top to bottom, so the code is more concise.
func main() {
score := 90
var ans string
if score >= 0 && score < 60 {
ans = "F"
} else if score < 70 {
ans = "D"
} else if score < 80 {
ans = "C"
} else if score < 90 {
ans = "B"
} else if score < 100 {
ans = "A"
} else if score == 100 {
ans = "S"
}else {
ans = "nil"
}
fmt.Println(ans)
}switch
switch is also a multi-branch conditional statement. The syntax is as follows:
switch expr {
case case1:
statement1
case case2:
statement2
default:
default statement
}A simple example:
func main() {
str := "a"
switch str {
case "a":
str += "a"
str += "c"
case "b":
str += "bb"
str += "aaaa"
default: // When all cases don't match, the default branch will be executed
str += "CCCC"
}
fmt.Println(str)
}You can also write some simple statements before the expression, such as declaring new variables:
func main() {
switch num := f(); { // equivalent to switch num := f(); true {
case num >= 0 && num <= 1:
num++
case num > 1:
num--
fallthrough
case num < 0:
num += num
}
}
func f() int {
return 1
}switch statements can also have no expression at the entry point.
func main() {
num := 2
switch { // equivalent to switch true {
case num >= 0 && num <= 1:
num++
case num > 1:
num--
case num < 0:
num *= num
}
fmt.Println(num)Use the fallthrough keyword to continue executing the next adjacent branch.
func main() {
num := 2
switch {
case num >= 0 && num <= 1:
num++
case num > 1:
num--
fallthrough // After executing this branch, continue to execute the next branch
case num < 0:
num += num
}
fmt.Println(num)
}label
Label statement, labels a block of code, can be a target for goto, break, continue. Example:
func main() {
A:
a := 1
B:
b := 2
}Simply using labels has no meaning. It needs to be combined with other keywords to be useful.
goto
goto transfers control to the statement with the corresponding label in the same function. Example:
func main() {
a := 1
if a == 1 {
goto A
} else {
fmt.Println("b")
}
A:
fmt.Println("a")
}In practical applications, goto is rarely used. Jumping around reduces code readability, and performance is also a concern.
Complete Example
The program below runs as-is: copy it into a file and execute go run main.go, or paste it into the Go Playground.
package main
import "fmt"
func classify(n int) string {
// The variable v is scoped to the if/else chain only
if v := n * 2; v > 10 {
return "large"
} else if v > 4 {
return "medium"
}
return "small"
}
func describe(v any) string {
switch x := v.(type) {
case nil:
return "nil"
case int:
return fmt.Sprintf("int %d", x)
case string:
return "string " + x
default:
return "unknown"
}
}
func main() {
fmt.Println(classify(3), classify(6))
for _, v := range []any{nil, 7, "go", 3.14} {
fmt.Println(describe(v))
}
}Expected output:
medium large
nil
int 7
string go
unknownCommon Pitfalls
- Conditions must be
bool.if 1 { }does not compile, and Go has no ternary operator. - Init statements leak nothing. Variables declared in the
ifheader are not visible after the chain. switchbreaks automatically. Addfallthroughexplicitly if you need it — and it cannot appear in the last case.- In a type switch, the variable's type changes per case. With
case int, string:the variable keeps the interface type, so you still need a type assertion. gotocannot jump over variable declarations, which is a common cause of confusing compile errors.
Change Log
- 2026-10-14: Added "Before You Start" notes, a complete runnable example with expected output, common pitfalls, and this change log.
