Chapter 32: Conditions
Conditions” or “Conditional Statements in Go”, they almost always mean:
How to make decisions in code — i.e. if, else if, else and especially Go’s very beloved if with initialization pattern
Go has no ternary operator (condition ? trueExpr : falseExpr), no Elvis operator, no switch expressions, no do-while, and no chained comparisons like 10 < x < 20.
So the if statement does almost all the decision-making work in Go — and it’s surprisingly elegant and powerful.
Let’s go through it step by step like we’re sitting together with VS Code open, writing small programs and running them live.
1. Basic if / else / else if – Syntax & Style Rules
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
package main import "fmt" func main() { temperature := 36 // The most basic form if temperature > 30 { fmt.Println("It's hot in Hyderabad today!") } // if + else if temperature >= 35 { fmt.Println("Very hot — stay indoors") } else { fmt.Println("Manageable weather") } // if + else if chain + else if temperature >= 40 { fmt.Println("Extreme heat warning") } else if temperature >= 35 { fmt.Println("Hot — drink water") } else if temperature >= 25 { fmt.Println("Warm — nice day") } else if temperature >= 15 { fmt.Println("Pleasant") } else { fmt.Println("Cold — wear jacket") } } |
Important Go style rules (2025–2026 community standard):
- Always use braces {} — even for one line → if x > 0 { return x } → never write if x > 0 return x
- No parentheses around the condition → if x > 0 { ← correct → if (x > 0) { ← legal but not idiomatic
- Prefer early returns over deep nesting → “happy path” stays on the left side
2. The Most Loved Go Feature: if with Initialization
This pattern is everywhere in real Go code.
You can declare one or more variables right inside the if statement — they are only visible inside that if/else block.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// Classic error handling pattern — you will write this hundreds of times file, err := os.Open("config.json") if err != nil { fmt.Println("Cannot open config:", err) return } // here file is usable, err is NOT visible anymore // Another very common style if length := len(username); length == 0 { fmt.Println("Username is required") } else if length < 3 { fmt.Println("Username too short") } else if length > 20 { fmt.Println("Username too long") } else { fmt.Println("Username looks good — length:", length) } // length is NOT visible here — scoped only to the if chain |
Why everyone loves this pattern:
- Variable lives only as long as needed
- No unnecessary variables hanging around in outer scope
- Very clean error handling idiom: if err != nil { return … }
3. Conditions with Logical & Comparison Operators
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
age := 19 hasLicense := false hasLearnersPermit := true isRaining := false // Multiple conditions if age >= 18 && hasLicense { fmt.Println("Can drive alone") } else if age >= 16 && hasLearnersPermit { fmt.Println("Can drive with adult supervisor") } else { fmt.Println("Cannot drive yet") } // Safe nil check + value check (short-circuit magic) var score *int = nil if score != nil && *score >= 90 { fmt.Println("Excellent score!") } else { fmt.Println("No score or below 90") } |
Short-circuit evaluation (extremely important):
- && stops as soon as it finds false
- || stops as soon as it finds true
→ This prevents crashes in the example above
4. Idiomatic Patterns You Will Use Every Day
Pattern 1: Guard clauses / early returns
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
func processUser(user *User) error { if user == nil { return ErrNilUser } if !user.IsActive { return ErrUserInactive } if !user.HasPermission("edit") { return ErrNoPermission } // happy path here return nil } |
Pattern 2: Input / parameter validation
|
0 1 2 3 4 5 6 7 8 9 10 11 |
if name == "" { return fmt.Errorf("name is required") } if len(name) < 2 || len(name) > 50 { return fmt.Errorf("name length must be 2–50 characters") } |
Pattern 3: Range checking
|
0 1 2 3 4 5 6 7 8 |
if port < 1 || port > 65535 { return fmt.Errorf("invalid port number: %d", port) } |
5. Quick Practice – Try Writing These
- Write an if chain that classifies temperature:
- < 0 → “Freezing ❄️”
- 0–15 → “Cold 🥶”
- 16–25 → “Pleasant 🌤️”
- 26–35 → “Warm ☀️”
-
35 → “Hot 🔥”
- Write a safe check: if a map key exists and its value > 100, print “High value”
- Write a function that returns early if input is invalid
Which style felt most comfortable — normal if-else or if-with-init?
Any part still unclear?
- Why no ternary operator in Go philosophy?
- How deep is too deep for if nesting?
- Short-circuit behavior with expensive function calls?
- Or ready to move to switch statement next?
Keep writing small if conditions — they are the heart of almost every meaningful decision in your future programs.
You’re doing fantastic — keep asking! 💪🇮🇳🚀
