Golang Backend Real-World (Part 4): Control Flow (if, for, switch, defer)
  • Golang
  • Golang Backend Real-World (Part 4): Control Flow (if, for, switch, defer)

    Control Flow in Golang: if, for, switch & defer

    Control flow determines how your program makes decisions, handles loops, and controls execution order.
    In real backend services—authentication, validation, routing, middleware, DB operations—control flow constructs appear everywhere.

    Go keeps these constructs simple, predictable, and highly consistent.


    1. if Statements

    Go’s if statements do not require parentheses and support an optional initialization statement.


    1.1 Basic if usage

    age := 20
    
    if age >= 18 {
        fmt.Println("Allowed")
    }
    

    1.2 if-else

    if age >= 18 {
        fmt.Println("Adult")
    } else {
        fmt.Println("Minor")
    }
    

    1.3 if with initialization

    Very common in backend code (e.g., database or cache lookups):

    if user, err := repo.GetUser(id); err == nil {
        fmt.Println("Found:", user.Name)
    } else {
        fmt.Println("User not found")
    }
    

    2. for Loops

    Go has only one loop keyword: for.
    It covers classic loops, while-loops, and infinite loops.


    2.1 Classic counter loop

    for i := 0; i < 5; i++ {
        fmt.Println(i)
    }
    

    2.2 Range loop (important for backend models and DTOs)

    users := []string{"alice", "bob"}
    
    for index, name := range users {
        fmt.Println(index, name)
    }
    

    Used everywhere when iterating JSON payloads, DB results, configs, etc.


    2.3 Infinite loop

    Used in workers, consumers, schedulers:

    for {
        processJob()
    }
    

    3. switch Statements

    More powerful than other languages — supports conditions, multiple cases, type switches, and more.


    3.1 Basic switch

    status := 200
    
    switch status {
    case 200:
        fmt.Println("OK")
    case 400:
        fmt.Println("Bad Request")
    default:
        fmt.Println("Unknown")
    }
    

    3.2 Multiple matches

    switch ext := "jpg"; ext {
    case "jpg", "jpeg":
        fmt.Println("Image file")
    case "mp4":
        fmt.Println("Video file")
    default:
        fmt.Println("Other type")
    }
    

    3.3 Type switch

    Used for handling interfaces in backend systems.

    func printType(v interface{}) {
        switch v.(type) {
        case int:
            fmt.Println("Integer")
        case string:
            fmt.Println("String")
        default:
            fmt.Println("Unknown")
        }
    }
    

    4. defer

    defer schedules a function to run after the current function finishes, similar to a “finally” block.

    Used extensively in backend systems for:

    • closing DB connections
    • releasing locks
    • closing file handles
    • logging

    4.1 Basic example

    func readFile() {
        f, _ := os.Open("data.txt")
        defer f.Close()  // always runs at the end
    
        fmt.Println("Reading file...")
    }
    

    4.2 Multiple defers execute LIFO

    defer fmt.Println("first")
    defer fmt.Println("second")
    

    Output:

    second
    first
    

    5. Summary

    In Part 4, you learned how Golang handles control flow using:

    if and if with initialization
    ✔ All versions of for loops
    switch for values and types
    defer for resource cleanup

    These constructs appear constantly in production backend development.

    Leaf

    "Thành công nuôi dưỡng sự hoàn hảo. Sự hoàn hảo lại nuôi lớn thất bại. Chỉ có trí tưởng tượng mới tồn tại."
    2 mins