Chapter 33: Go if statement
Go if statement in tutorials (Tour of Go, W3Schools, freeCodeCamp, GeeksforGeeks, YouTube beginner videos, etc.), they usually mean:
The complete guide to writing conditional logic using if, else if, else
- Go’s very famous and very idiomatic feature: if with short variable declaration (initialization)
Go’s if is extremely clean, very strict, and surprisingly powerful — especially because of the initialization pattern you’ll see in almost every real Go function.
Let’s go through everything step by step like we’re sitting together with VS Code open, writing small programs, running them, and discussing why Go made each choice.
1. Basic Syntax – No Parentheses, Always Braces
|
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 := 38 // The simplest form if temperature > 35 { fmt.Println("It's very hot in Hyderabad today!") } // if + else if temperature >= 40 { fmt.Println("Extreme heat warning ☀️🔥") } else { fmt.Println("Still hot, but not extreme") } // if + else if chain + else if temperature >= 45 { fmt.Println("Dangerous heat — stay indoors") } else if temperature >= 40 { fmt.Println("Very hot — hydrate!") } else if temperature >= 35 { fmt.Println("Hot — avoid direct sun") } else if temperature >= 25 { fmt.Println("Warm and pleasant") } else { fmt.Println("Cooler weather — enjoy!") } } |
Important style rules (2025–2026 Go community standard):
- No parentheses around the condition → if temperature > 35 { ← correct → if (temperature > 35) { ← legal but not idiomatic
- Braces {} are mandatory — even for one line → if x > 0 { return x } → never write if x > 0 return x — Go forbids it
2. The Star Feature: if with Short Variable Declaration
This pattern is one of the things people love most about Go.
You can declare one or more variables right inside the if — they are only visible inside that if / else 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 25 |
// Classic real-world example — you will write this hundreds of times file, err := os.Open("config.json") if err != nil { fmt.Println("Failed to open file:", err) return } // here 'file' is usable, 'err' is NOT visible anymore // Another very common style username := "webliance" 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/else chain |
Why this is so powerful & idiomatic:
- Variables live only as long as needed
- No unnecessary variables polluting the outer scope
- Extremely common error-handling pattern: if err != nil { return … }
- Reduces bugs from using old/wrong variables
3. Combining with Comparison & Logical 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 |
age := 19 hasLicense := false hasPermit := true isRaining := false if age >= 18 && hasLicense { fmt.Println("Can drive alone") } else if age >= 16 && hasPermit { fmt.Println("Can drive with adult supervisor") } else { fmt.Println("Cannot drive yet") } // Safe nil check + value check (short-circuit evaluation) var score *int = nil if score != nil && *score >= 90 { fmt.Println("Excellent score!") } else { fmt.Println("No score or below 90") } |
Short-circuit evaluation — very important safety feature:
- && stops as soon as it finds false
- || stops as soon as it finds true
→ This prevents panic in the example above
4. Idiomatic Patterns You Will Use Every Day
Pattern 1: Guard clauses / early returns (very common in real code)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
func processOrder(order *Order) error { if order == nil { return ErrNilOrder } if order.Status != "pending" { return ErrInvalidStatus } if order.Amount <= 0 { return ErrInvalidAmount } // happy path continues here return nil } |
Pattern 2: Input validation at beginning
|
0 1 2 3 4 5 6 7 8 9 10 11 |
if email == "" { return fmt.Errorf("email is required") } if !strings.Contains(email, "@") { return fmt.Errorf("invalid email format") } |
Pattern 3: Range / bound checking
|
0 1 2 3 4 5 6 7 8 |
if port < 1 || port > 65535 { return fmt.Errorf("port must be between 1 and 65535, got %d", port) } |
5. Quick Practice – Try Writing These
- Write an if-else chain that classifies temperature in Hyderabad:
- < 10 → “Really cold ❄️”
- 10–20 → “Cool 🧥”
- 21–30 → “Pleasant 🌤️”
- 31–38 → “Hot ☀️”
-
38 → “Very hot 🔥”
- Write a safe check: if a slice is not niland has length > 0 and first element > 100, print “Strong start”
- Write a function that returns early if any input is invalid
Which style do you prefer — long if-else chains or early returns?
Any part still confusing?
- Why Go forces braces {} even for one line?
- Why no ternary operator? (Go philosophy)
- How deep is too deep for if nesting?
- Or ready to move to switch statement next?
Keep writing small if conditions — they are the control center of almost every meaningful program you’ll write.
You’re doing really great — keep asking! 💪🇮🇳🚀
