Chapter 28: Comparison
Comparison operators — the operators you use to make decisions, check conditions, sort things, validate input, filter data, etc.
In almost every real Go program (web handlers, CLI tools, data processing, games, APIs…), comparison operators appear many times per function.
Go’s comparison operators are very clean, very strict, very predictable — no weird JavaScript type coercion, no Python chaining surprises.
Let’s go through everything about comparison in Go like a patient human teacher would explain it — slowly, with many examples you can copy-paste and run right now.
1. The Six Comparison Operators in Go
| Operator | Meaning | Works on types | Example | Result | Important notes |
|---|---|---|---|---|---|
| == | equal to | almost all types (numbers, bool, string, array, struct, pointer, etc.) | 5 == 5 “hi” == “hi” | true | byte-by-byte for strings |
| != | not equal to | same as == | 3 != 4 true != false | true | — |
| < | less than | numbers, strings | 10 < 20 “apple” < “banana” | true | lexicographical for strings |
| <= | less than or equal | numbers, strings | 5 <= 5 | true | — |
| > | greater than | numbers, strings | 100 > 50 | true | — |
| >= | greater than or equal | numbers, strings | 0 >= -1 | true | — |
Very important Go rules:
- Comparison operators do NOT chain like in Python → 10 < x < 20 → compile error
- You cannot compare different types without explicit conversion → 5 == 5.0 → compile error (int vs float64)
- Strings are compared byte by byte (lexicographical order based on UTF-8 byte values)
2. Runnable Examples — Copy-Paste & Run These
Create comparison_operators.go:
|
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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
package main import "fmt" func main() { // ──────────────────────────────────────────────── // 1. Numbers – most common use // ──────────────────────────────────────────────── age := 25 minAge := 18 fmt.Println("Numbers:") fmt.Println("age == 25 →", age == 25) // true fmt.Println("age != 30 →", age != 30) // true fmt.Println("age > minAge →", age > minAge) // true fmt.Println("age >= 25 →", age >= 25) // true fmt.Println("age < 18 →", age < 18) // false // float comparison (be careful with precision!) pi := 3.14159 approx := 3.14 fmt.Println("pi == approx →", pi == approx) // false fmt.Println("pi > approx →", pi > approx) // true // ──────────────────────────────────────────────── // 2. Strings – byte-by-byte lexicographical order // ──────────────────────────────────────────────── city1 := "Hyderabad" city2 := "Bangalore" city3 := "hyderabad" // lowercase h fmt.Println("\nStrings:") fmt.Println(`"Hyderabad" == "Hyderabad" →`, city1 == "Hyderabad") // true fmt.Println(`"Hyderabad" != "hyderabad" →`, city1 != city3) // true fmt.Println(`"Hyderabad" < "Bangalore" →`, city1 < city2) // false (H > B) fmt.Println(`"apple" < "banana" →`, "apple" < "banana") // true fmt.Println(`"Zoo" < "apple" →`, "Zoo" < "apple") // false (Z > a) // ──────────────────────────────────────────────── // 3. Booleans // ──────────────────────────────────────────────── isStudent := true hasLaptop := false fmt.Println("\nBooleans:") fmt.Println("isStudent == true →", isStudent == true) // true fmt.Println("hasLaptop != true →", hasLaptop != true) // true // ──────────────────────────────────────────────── // 4. Common real-world patterns // ──────────────────────────────────────────────── temperature := 35.2 isHot := temperature >= 32.0 fmt.Println("Is hot in Hyderabad? ", isHot) // true password := "secret123" input := "Secret123" isMatch := password == input fmt.Println("Password match? ", isMatch) // false (case-sensitive) } |
3. Very Important Gotchas & Rules
- No automatic type conversion in comparisons
|
0 1 2 3 4 5 6 7 8 9 10 |
var i int = 5 var f float64 = 5.0 // if i == f { } → compile error: invalid operation: i == f (mismatched types int and float64) if float64(i) == f { fmt.Println("Equal after conversion") } // correct |
- No chaining of comparisons
|
0 1 2 3 4 5 6 7 8 9 10 11 |
// This is INVALID in Go if 10 < age < 30 { } // compile error // Correct ways if age > 10 && age < 30 { } if 10 < age && age < 30 { } |
- String comparison is case-sensitive and byte-based
|
0 1 2 3 4 5 6 7 |
"Apple" < "apple" // false (A = 65, a = 97 → uppercase comes first) "Hyderabad" < "hyderabad" // false |
- Floating-point comparison is exact (dangerous!)
|
0 1 2 3 4 5 6 7 |
a := 0.1 + 0.2 fmt.Println(a == 0.3) // false ! (floating point precision) |
Never use == for floats unless you really know what you’re doing. Use small epsilon instead:
|
0 1 2 3 4 5 6 7 |
const epsilon = 1e-9 if math.Abs(a-0.3) < epsilon { fmt.Println("Approximately equal") } |
4. Real-World Patterns You Will Use Every Day
|
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 |
// 1. Age validation if age < 18 { fmt.Println("Minor") } else if age >= 18 && age < 60 { fmt.Println("Adult") } else { fmt.Println("Senior") } // 2. String prefix / suffix check if strings.HasPrefix(url, "https://") { ... } // 3. Sorting / searching if score > bestScore { bestScore = score leader = name } // 4. Safe nil check before dereference if ptr != nil && *ptr > 0 { ... } |
5. Quick Practice – Try These Mentally or Run Them
Predict the result:
- “telangana” < “Telangana” → ?
- 25 == 25.0 → ?
- -5 < 0 → ?
- true == false → ?
- “హైదరాబాద్” == “Hyderabad” → ?
(Answers: false, compile error, true, false, false)
Any part still fuzzy?
- Why no <=> three-way comparison like some languages?
- How string comparison really works with Unicode/emoji?
- Floating-point equality strategies?
- Or ready for logical operators (&&, ||, !) next?
Keep typing small comparison expressions and printing results — these operators control almost every if, for, switch, sort, filter, validation in your future code.
You’re doing really well — keep asking! 💪🇮🇳🚀
