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