Skip to content

Go Conditional Statements

Conditional statements are an important part of program control flow, allowing programs to execute different code paths based on different conditions. Go provides two main conditional control structures: if and switch.

🔀 if Statement

Basic if Statement

go
package main

import "fmt"

func main() {
    age := 18
    
    // Basic if statement
    if age >= 18 {
        fmt.Println("You are an adult")
    }
    
    // if-else statement
    score := 85
    if score >= 90 {
        fmt.Println("Excellent")
    } else {
        fmt.Println("Good")
    }
    
    // Multiple condition judgment
    temperature := 25
    if temperature < 0 {
        fmt.Println("Weather is very cold")
    } else if temperature < 20 {
        fmt.Println("Weather is cool")
    } else if temperature < 30 {
        fmt.Println("Weather is warm")
    } else {
        fmt.Println("Weather is hot")
    }
}

Special Syntax of if Statement

Initialization Statement

go
func main() {
    // if statement can contain an initialization statement
    if num := 42; num > 0 {
        fmt.Printf("%d is positive\n", num)
    }
    // Note: num variable is only valid within the if block
    
    // Practical application: handle function return values
    if result, err := divide(10, 2); err != nil {
        fmt.Printf("Error: %v\n", err)
    } else {
        fmt.Printf("Result: %.2f\n", result)
    }
    
    // Check key in map
    userAges := map[string]int{
        "Alice": 25,
        "Bob":   30,
    }
    
    if age, exists := userAges["Alice"]; exists {
        fmt.Printf("Alice's age is %d\n", age)
    } else {
        fmt.Println("Cannot find Alice's age information")
    }
}

func divide(a, b float64) (float64, error) {
    if b == 0 {
        return 0, fmt.Errorf("Divisor cannot be zero")
    }
    return a / b, nil
}

Complex Condition Judgment

go
import "strings"

func main() {
    // Combine conditions with logical operators
    username := "admin"
    password := "123456"
    isActive := true
    
    if username == "admin" && password == "123456" && isActive {
        fmt.Println("Admin login successful")
    } else {
        fmt.Println("Login failed")
    }
    
    // String condition judgment
    email := "user@example.com"
    if strings.Contains(email, "@") && strings.Contains(email, ".") {
        fmt.Println("Email format looks correct")
    } else {
        fmt.Println("Email format is incorrect")
    }
    
    // Numeric range judgment
    score := 95
    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.Printf("Score %d corresponds to grade %s\n", score, grade)
}

🔄 switch Statement

Basic switch Statement

go
func main() {
    // Basic switch statement
    day := 3
    switch day {
    case 1:
        fmt.Println("Monday")
    case 2:
        fmt.Println("Tuesday")
    case 3:
        fmt.Println("Wednesday")
    case 4:
        fmt.Println("Thursday")
    case 5:
        fmt.Println("Friday")
    case 6, 7:  // Multiple values match same case
        fmt.Println("Weekend")
    default:
        fmt.Println("Invalid date")
    }
    
    // String switch
    operation := "add"
    switch operation {
    case "add":
        fmt.Println("Perform addition")
    case "subtract":
        fmt.Println("Perform subtraction")
    case "multiply":
        fmt.Println("Perform multiplication")
    case "divide":
        fmt.Println("Perform division")
    default:
        fmt.Println("Unknown operation")
    }
}

Advanced Features of switch Statement

switch with Initialization

go
import "time"

func main() {
    // switch statement can contain initialization statement
    switch hour := time.Now().Hour(); {
    case hour < 6:
        fmt.Println("Early morning")
    case hour < 12:
        fmt.Println("Morning")
    case hour < 18:
        fmt.Println("Afternoon")
    default:
        fmt.Println("Evening")
    }
    
    // Call function in switch
    switch result := calculateGrade(85); result {
    case "A":
        fmt.Println("Excellent grade!")
    case "B":
        fmt.Println("Good grade!")
    case "C":
        fmt.Println("Passing grade!")
    default:
        fmt.Println("Need to work harder!")
    }
}

func calculateGrade(score int) string {
    if score >= 90 {
        return "A"
    } else if score >= 80 {
        return "B"
    } else if score >= 70 {
        return "C"
    }
    return "D"
}

switch without Expression

go
func main() {
    x := 15
    
    // switch without expression (equivalent to if-else chain)
    switch {
    case x < 0:
        fmt.Println("x is negative")
    case x == 0:
        fmt.Println("x is zero")
    case x > 0 && x < 10:
        fmt.Println("x is a single-digit positive number")
    case x >= 10 && x < 100:
        fmt.Println("x is a two-digit positive number")
    default:
        fmt.Println("x is greater than or equal to 100")
    }
    
    // Complex condition judgment
    temperature := 25
    humidity := 60
    
    switch {
    case temperature > 30 && humidity > 70:
        fmt.Println("Hot and humid, uncomfortable")
    case temperature > 30:
        fmt.Println("Weather is hot")
    case temperature < 10:
        fmt.Println("Weather is cold")
    case humidity > 80:
        fmt.Println("Humidity is very high")
    default:
        fmt.Println("Weather is comfortable")
    }
}

fallthrough Keyword

go
func main() {
    grade := "B"
    
    // fallthrough continues to execute next case
    switch grade {
    case "A":
        fmt.Println("Excellent!")
        fallthrough
    case "B":
        fmt.Println("Good!")
        fallthrough
    case "C":
        fmt.Println("Pass!")
        // No fallthrough, won't continue
    case "D":
        fmt.Println("Fail!")
    default:
        fmt.Println("Invalid grade")
    }
    
    // Output:
    // Good!
    // Pass!
    
    // Note: fallthrough must be the last statement in the case block
    processNumber := func(n int) {
        switch n {
        case 1:
            fmt.Println("Processing number 1")
            // Some logic processing
            fallthrough
        case 2:
            fmt.Println("Common processing for numbers 1 and 2")
        case 3:
            fmt.Println("Processing number 3")
        }
    }
    
    processNumber(1)
    fmt.Println("---")
    processNumber(2)
}

Type switch

go
import "fmt"

func main() {
    // Type switch is used to determine the actual type of interface variable
    var x interface{} = 42
    
    switch v := x.(type) {
    case int:
        fmt.Printf("x is int type, value %d\n", v)
    case string:
        fmt.Printf("x is string type, value %s\n", v)
    case bool:
        fmt.Printf("x is bool type, value %t\n", v)
    case float64:
        fmt.Printf("x is float64 type, value %f\n", v)
    default:
        fmt.Printf("x is unknown type %T\n", v)
    }
    
    // Process different types of data
    processValue := func(value interface{}) {
        switch v := value.(type) {
        case nil:
            fmt.Println("Value is nil")
        case int, int32, int64:
            fmt.Printf("Integer value: %v\n", v)
        case float32, float64:
            fmt.Printf("Floating-point value: %v\n", v)
        case string:
            fmt.Printf("String value: %q\n", v)
        case []int:
            fmt.Printf("Integer slice: %v\n", v)
        default:
            fmt.Printf("Unhandled type: %T\n", v)
        }
    }
    
    processValue(42)
    processValue(3.14)
    processValue("hello")
    processValue([]int{1, 2, 3})
    processValue(true)
}

🎯 Practical Application Examples

User Permission Verification System

go
import (
    "fmt"
    "strings"
)

// User roles
const (
    RoleAdmin = "admin"
    RoleUser  = "user"
    RoleGuest = "guest"
)

// Permission levels
const (
    PermissionNone   = 0
    PermissionRead   = 1
    PermissionWrite  = 2
    PermissionDelete = 3
)

type User struct {
    Username   string
    Role       string
    IsActive   bool
    Permission int
}

func main() {
    users := []User{
        {"admin", RoleAdmin, true, PermissionDelete},
        {"john", RoleUser, true, PermissionWrite},
        {"guest", RoleGuest, true, PermissionRead},
        {"inactive", RoleUser, false, PermissionWrite},
    }
    
    for _, user := range users {
        checkUserAccess(user, "delete_file")
        fmt.Println("---")
    }
}

func checkUserAccess(user User, action string) {
    // First check if user is active
    if !user.IsActive {
        fmt.Printf("User %s account is not active, access denied\n", user.Username)
        return
    }
    
    // Role-based access control
    switch user.Role {
    case RoleAdmin:
        fmt.Printf("Admin %s has all permissions\n", user.Username)
        performAction(action)
    case RoleUser:
        // Check specific permissions
        if checkPermission(user.Permission, action) {
            fmt.Printf("User %s has permission to execute %s\n", user.Username, action)
            performAction(action)
        } else {
            fmt.Printf("User %s has insufficient permissions, cannot execute %s\n", user.Username, action)
        }
    case RoleGuest:
        // Guests can only read
        if strings.HasPrefix(action, "read") {
            fmt.Printf("Guest %s can execute read-only operation %s\n", user.Username, action)
            performAction(action)
        } else {
            fmt.Printf("Guest %s can only execute read-only operations\n", user.Username)
        }
    default:
        fmt.Printf("Unknown role, access denied\n")
    }
}

func checkPermission(userPermission int, action string) bool {
    switch action {
    case "read_file", "view_data":
        return userPermission >= PermissionRead
    case "write_file", "update_data":
        return userPermission >= PermissionWrite
    case "delete_file", "delete_data":
        return userPermission >= PermissionDelete
    default:
        return false
    }
}

func performAction(action string) {
    fmt.Printf("  -> Execute operation: %s\n", action)
}

HTTP Status Code Handling

go
import (
    "fmt"
    "net/http"
)

func main() {
    // Simulate different HTTP status codes
    statusCodes := []int{200, 201, 400, 401, 403, 404, 500, 502, 503}
    
    for _, code := range statusCodes {
        handleHTTPStatus(code)
    }
}

func handleHTTPStatus(statusCode int) {
    fmt.Printf("Processing status code %d: ", statusCode)
    
    switch {
    case statusCode >= 200 && statusCode < 300:
        // 2xx success status codes
        switch statusCode {
        case http.StatusOK:
            fmt.Println("Request successful")
        case http.StatusCreated:
            fmt.Println("Resource created successfully")
        case http.StatusAccepted:
            fmt.Println("Request accepted")
        case http.StatusNoContent:
            fmt.Println("Request successful, no content returned")
        default:
            fmt.Println("Other success status")
        }
        
    case statusCode >= 300 && statusCode < 400:
        // 3xx redirect status codes
        fmt.Println("Redirect required")
        
    case statusCode >= 400 && statusCode < 500:
        // 4xx client errors
        switch statusCode {
        case http.StatusBadRequest:
            fmt.Println("Request parameter error")
        case http.StatusUnauthorized:
            fmt.Println("Authentication required")
        case http.StatusForbidden:
            fmt.Println("Access forbidden")
        case http.StatusNotFound:
            fmt.Println("Resource not found")
        case http.StatusMethodNotAllowed:
            fmt.Println("Request method not allowed")
        default:
            fmt.Println("Other client errors")
        }
        
    case statusCode >= 500:
        // 5xx server errors
        switch statusCode {
        case http.StatusInternalServerError:
            fmt.Println("Internal server error")
        case http.StatusBadGateway:
            fmt.Println("Gateway error")
        case http.StatusServiceUnavailable:
            fmt.Println("Service unavailable")
        case http.StatusGatewayTimeout:
            fmt.Println("Gateway timeout")
        default:
            fmt.Println("Other server errors")
        }
        
    default:
        fmt.Println("Unknown status code")
    }
}

Calculator Application

go
import (
    "fmt"
    "math"
)

func main() {
    calculator := NewCalculator()
    
    // Test various operations
    testCases := []struct {
        a, b      float64
        operation string
    }{
        {10, 5, "add"},
        {10, 5, "subtract"},
        {10, 5, "multiply"},
        {10, 5, "divide"},
        {10, 0, "divide"}, // Division by zero test
        {16, 0, "sqrt"},
        {2, 8, "power"},
        {10, 5, "unknown"}, // Unknown operation
    }
    
    for _, test := range testCases {
        result, err := calculator.Calculate(test.a, test.b, test.operation)
        if err != nil {
            fmt.Printf("%.1f %s %.1f = Error: %v\n", test.a, test.operation, test.b, err)
        } else {
            if test.operation == "sqrt" {
                fmt.Printf("%s(%.1f) = %.2f\n", test.operation, test.a, result)
            } else {
                fmt.Printf("%.1f %s %.1f = %.2f\n", test.a, test.operation, test.b, result)
            }
        }
    }
}

type Calculator struct{}

func NewCalculator() *Calculator {
    return &Calculator{}
}

func (c *Calculator) Calculate(a, b float64, operation string) (float64, error) {
    switch operation {
    case "add", "+":
        return a + b, nil
        
    case "subtract", "-":
        return a - b, nil
        
    case "multiply", "*":
        return a * b, nil
        
    case "divide", "/":
        if b == 0 {
            return 0, fmt.Errorf("Divisor cannot be zero")
        }
        return a / b, nil
        
    case "power", "^":
        return math.Pow(a, b), nil
        
    case "sqrt":
        if a < 0 {
            return 0, fmt.Errorf("Negative numbers have no real square root")
        }
        return math.Sqrt(a), nil
        
    case "mod", "%":
        if b == 0 {
            return 0, fmt.Errorf("Modulus cannot be zero")
        }
        return math.Mod(a, b), nil
        
    default:
        return 0, fmt.Errorf("Unsupported operation: %s", operation)
    }
}

💡 Best Practices

Conditional Statement Optimization

go
func main() {
    // ❌ Avoid deep nesting
    badExample := func(user User) {
        if user.IsActive {
            if user.Role == "admin" {
                if user.Permission >= PermissionWrite {
                    fmt.Println("Access granted")
                } else {
                    fmt.Println("Insufficient permissions")
                }
            } else {
                fmt.Println("Not admin")
            }
        } else {
            fmt.Println("User not active")
        }
    }
    
    // ✅ Use early return
    goodExample := func(user User) {
        if !user.IsActive {
            fmt.Println("User not active")
            return
        }
        
        if user.Role != "admin" {
            fmt.Println("Not admin")
            return
        }
        
        if user.Permission < PermissionWrite {
            fmt.Println("Insufficient permissions")
            return
        }
        
        fmt.Println("Access granted")
    }
    
    testUser := User{"test", RoleAdmin, true, PermissionWrite}
    
    fmt.Println("Bad example:")
    badExample(testUser)
    
    fmt.Println("Good example:")
    goodExample(testUser)
}

Use switch Instead of Long if-else Chains

go
func main() {
    // ❌ Long if-else chain
    gradeToGPA_Bad := func(grade string) float64 {
        if grade == "A+" {
            return 4.0
        } else if grade == "A" {
            return 4.0
        } else if grade == "A-" {
            return 3.7
        } else if grade == "B+" {
            return 3.3
        } else if grade == "B" {
            return 3.0
        } else if grade == "B-" {
            return 2.7
        } else if grade == "C+" {
            return 2.3
        } else if grade == "C" {
            return 2.0
        } else if grade == "C-" {
            return 1.7
        } else if grade == "D" {
            return 1.0
        } else {
            return 0.0
        }
    }
    
    // ✅ Use switch
    gradeToGPA_Good := func(grade string) float64 {
        switch grade {
        case "A+", "A":
            return 4.0
        case "A-":
            return 3.7
        case "B+":
            return 3.3
        case "B":
            return 3.0
        case "B-":
            return 2.7
        case "C+":
            return 2.3
        case "C":
            return 2.0
        case "C-":
            return 1.7
        case "D":
            return 1.0
        default:
            return 0.0
        }
    }
    
    grades := []string{"A", "B+", "C", "D", "F"}
    
    fmt.Println("Grade to GPA:")
    for _, grade := range grades {
        gpa1 := gradeToGPA_Bad(grade)
        gpa2 := gradeToGPA_Good(grade)
        fmt.Printf("%s: %.1f (Same result from both methods: %t)\n", grade, gpa1, gpa1 == gpa2)
    }
}

🎓 Summary

In this chapter, we comprehensively learned about Go conditional statements:

  • if Statement: basic syntax, initialization statements, complex condition judgment
  • switch Statement: basic usage, multi-value matching, expressionless switch
  • Special Features: fallthrough keyword, type switch
  • Practical Applications: permission system, status handling, calculator application
  • Best Practices: avoid deep nesting, optimize condition chains

Conditional statements are the core of program logic control. Using them correctly can make code clearer and more efficient.


Next, we will learn Go Loop Statements to master program repetition control.

Conditional Statement Usage Suggestions

  • Prefer early returns to avoid deep nesting
  • Consider using switch for long if-else chains
  • Make good use of switch initialization statements and type judgment
  • Pay attention to usage scenarios and limitations of fallthrough

Content is for learning and research only.