Control Flow
Go keeps control flow simple: if, for, and switch cover all the ground that other languages handle with additional keywords like while, do, and foreach.
If / Else
The condition requires no parentheses, but the braces are mandatory:
package main
import "fmt"
func classify(n int) string {
if n < 0 {
return "negative"
} else if n == 0 {
return "zero"
} else {
return "positive"
}
}
func main() {
fmt.Println(classify(-5)) // negative
fmt.Println(classify(0)) // zero
fmt.Println(classify(7)) // positive
}Initialisation Statement
if accepts an optional short statement before the condition. Variables declared here are scoped to the if/else block:
package main
import (
"fmt"
"strconv"
)
func parseAndDouble(s string) {
if n, err := strconv.Atoi(s); err == nil {
fmt.Println(n * 2)
} else {
fmt.Println("not a number:", err)
}
}
func main() {
parseAndDouble("21") // 42
parseAndDouble("oops") // not a number: ...
}The for Loop
Go has exactly one looping keyword: for. It covers every looping pattern:
package main
import "fmt"
func main() {
// Classic three-component loop
for i := 0; i < 5; i++ {
fmt.Print(i, " ")
}
fmt.Println()
// Condition-only (equivalent to while)
n := 1
for n < 100 {
n *= 2
}
fmt.Println(n) // 128
// Infinite loop — use break to exit
count := 0
for {
count++
if count == 3 {
break
}
}
fmt.Println(count) // 3
}Idiomatic Go: Go has no
whilekeyword. Usefor condition { }as a while loop andfor { }as an infinite loop.
Range
The range form iterates over slices, arrays, maps, strings, and channels:
package main
import "fmt"
func main() {
fruits := []string{"apple", "banana", "cherry"}
for i, fruit := range fruits {
fmt.Printf("%d: %s\n", i, fruit)
}
// Ignore the index with _
for _, fruit := range fruits {
fmt.Println(fruit)
}
}Switch
Go's switch does not fall through by default (unlike C/Java). Each case is independent:
package main
import "fmt"
func dayType(day string) string {
switch day {
case "Saturday", "Sunday":
return "weekend"
case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday":
return "weekday"
default:
return "unknown"
}
}
func main() {
fmt.Println(dayType("Monday")) // weekday
fmt.Println(dayType("Saturday")) // weekend
}Switch with No Condition
A switch with no condition is a cleaner alternative to a chain of if/else if:
package main
import "fmt"
func score(n int) string {
switch {
case n >= 90:
return "A"
case n >= 80:
return "B"
case n >= 70:
return "C"
default:
return "F"
}
}
func main() {
fmt.Println(score(95)) // A
fmt.Println(score(82)) // B
fmt.Println(score(65)) // F
}Fallthrough
Use fallthrough explicitly when you want the next case to execute as well:
package main
import "fmt"
func main() {
n := 2
switch n {
case 1:
fmt.Println("one")
fallthrough
case 2:
fmt.Println("two")
fallthrough
case 3:
fmt.Println("three")
case 4:
fmt.Println("four")
}
// Prints: two, three
}break and continue
breakexits the innermost loop or switch.continueskips to the next iteration of the innermost loop.
Labels allow breaking out of nested loops:
package main
import "fmt"
func main() {
outer:
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
if i == 1 && j == 1 {
break outer
}
fmt.Println(i, j)
}
}
}Key Takeaways
ifandswitchconditions need no parentheses; braces are required.- Go has one looping construct:
for. It covers classic, while-style, and infinite loops. rangeiterates over slices, maps, strings, and channels idiomatically.switchcases do not fall through by default; usefallthroughexplicitly.