← Go EnglishChapter 04 of 13

Control Flow

## Learning Objectives - Master if, else if, else statements - Understand switch statements - Learn for loops and variants - Use defer for cleanup ## if Statement ### Basic if ```go age := 18 if age >= 18 { fmt.Println("Adult") } ``` ### if-else ```go age := 15 if age >= 18 { fmt.Println("Adult") } else { fmt.Println("Minor") } ``` ### if-else if-else ```go score := 85 var grade string if score >= 90 { grade = "A" } else if score >= 80 { grade = "B" } else if score >= 70 { grade = "C" } else if score >= 60 { grade = "D" } else { grade = "F" } fmt.Println("Grade:", grade) ``` ### With Initialization ```go if err := doSomething(); err != nil { fmt.Println("Error:", err) return } ``` ## switch Statement ### Basic switch ```go day := 3 var dayName string switch day { case 1: dayName = "Monday" case 2: dayName = "Tuesday" case 3: dayName = "Wednesday" case 4: dayName = "Thursday" case 5: dayName = "Friday" case 6: dayName = "Saturday" case 7: dayName = "Sunday" default: dayName = "Invalid" } fmt.Println(dayName) ``` ### Multiple Values ```go month := 4 var days int switch month { case 1, 3, 5, 7, 8, 10, 12: days = 31 case 4, 6, 9, 11: days = 30 case 2: days = 28 default: days = 0 } ``` ### No Expression ```go num := 10 switch { case num < 0: fmt.Println("Negative") case num == 0: fmt.Println("Zero") case num > 0: fmt.Println("Positive") } ``` ### fallthrough ```go score := 75 var grade string switch { case score >= 90: grade = "A" case score >= 80: grade = "B" case score >= 70: grade = "C" fallthrough // Continues to next case case score >= 60: grade = "D" default: grade = "F" } ``` ## for Loop ### Basic for ```go for i := 0; i < 5; i++ { fmt.Println(i) // 0, 1, 2, 3, 4 } ``` ### Alternative Syntax ```go i := 0 for i < 5 { fmt.Println(i) i++ } ``` ### Infinite Loop ```go for { fmt.Println("Forever") if done { break } } ``` ### Range Loop ```go nums := []int{1, 2, 3, 4, 5} for i, v := range nums { fmt.Printf("Index: %d, Value: %d\n", i, v) } // Ignore index for _, v := range nums { fmt.Println(v) } // Index only for i := range nums { fmt.Println(i) } ``` ### String Iteration ```go str := "Hello" for i, r := range str { fmt.Printf("Index: %d, Rune: %c\n", i, r) } ``` ### Map Iteration ```go ages := map[string]int{ "Alice": 30, "Bob": 25, } for key, value := range ages { fmt.Printf("%s: %d\n", key, value) } ``` ### Channel Iteration ```go ch := make(chan int, 5) ch <- 1 ch <- 2 ch <- 3 close(ch) for v := range ch { fmt.Println(v) } ``` ## while Equivalent Go has no `while` keyword. Use `for` without initialization and post statement. ```go n := 1 for n < 100 { n *= 2 } fmt.Println("Result:", n) ``` ## break and continue ### break - Exit Loop ```go for i := 0; i < 10; i++ { if i == 5 { break // Exit when i is 5 } fmt.Println(i) // 0, 1, 2, 3, 4 } ``` ### continue - Skip Iteration ```go for i := 0; i < 5; i++ { if i == 2 { continue // Skip when i is 2 } fmt.Println(i) // 0, 1, 3, 4 } ``` ### Labeled break ```go outer: for i := 0; i < 5; i++ { for j := 0; j < 5; j++ { if j == 2 { break outer // Breaks outer loop } fmt.Printf("(%d,%d) ", i, j) } } fmt.Println() ``` ## Nested Loops ```go for i := 0; i < 3; i++ { for j := 0; j < 3; j++ { fmt.Printf("(%d,%d) ", i, j) } fmt.Println() } // Output: // (0,0) (0,1) (0,2) // (1,0) (1,1) (1,2) // (2,0) (2,1) (2,2) ``` ## defer ### Basic defer ```go func readFile(filename string) { file, err := os.Open(filename) if err != nil { return } defer file.Close() // Executes when function returns // Read file... } ``` ### Multiple defers ```go func example() { defer fmt.Println("1") defer fmt.Println("2") defer fmt.Println("3") } fmt.Println("Main") // Output: Main, 3, 2, 1 (LIFO order) ``` ### defer with Arguments ```go func example() { x := 10 defer fmt.Println("Deferred:", x) // Prints 10, not 20 x = 20 fmt.Println("Main:", x) } // Output: Main: 20, Deferred: 10 ``` ### Common Uses ```go // Unlock mutex mu.Lock() defer mu.Unlock() // Close database connection db, err := sql.Open(...) defer db.Close() // Print function entry/exit func trace(name string) { fmt.Println("Entering:", name) defer fmt.Println("Exiting:", name) } ``` ## return Statements ### Named Return Values ```go func rectangleProperties(width, height float64) (area, perimeter float64) { area = width * height perimeter = 2 * (width + height) return // Naked return } ``` ### Early Return ```go func findItem(items []int, target int) int { for i, item := range items { if item == target { return i // Early return when found } } return -1 // Not found } ``` ## goto Statement ### Using goto ```go func example() { for i := 0; i < 5; i++ { if i == 3 { goto done } fmt.Println(i) } done: fmt.Println("Finished") } ``` ## Common Patterns ### Sum 1 to N ```go sum := 0 for i := 1; i <= 100; i++ { sum += i } fmt.Println("Sum:", sum) ``` ### Find in Slice ```go nums := []int{3, 7, 2, 9, 4} target := 9 for i, num := range nums { if num == target { fmt.Println("Found at index:", i) break } } ``` ### Count Matches ```go nums := []int{1, 2, 3, 2, 4, 2, 5} target := 2 count := 0 for _, num := range nums { if num == target { count++ } } fmt.Println("Count:", count) ``` ### Fibonacci ```go a, b := 0, 1 for i := 0; i < 10; i++ { fmt.Print(a, " ") a, b = b, a+b } ``` ## Summary - if/else if/else for conditional logic - switch for multiple discrete values (with multiple cases) - for is the only loop keyword in Go - range loops iterate over slices, maps, strings, channels - break exits loop; continue skips iteration - defer executes code when function returns (LIFO order) - Use labeled break for nested loop control - goto is available but use sparingly

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →