Chapter 24: Go Operators
Go Operators — one of the very first things every beginner needs to feel comfortable with, because almost every line of real code uses them.
Operators in Go are very clean and minimal compared to many other languages — no surprises like JavaScript’s == vs ===, no Python’s ** power operator, no C++ overloading mess. Go has exactly the operators you expect from a modern C-family language, with very few additions and almost no weird behaviors.
I’ll explain them like we’re sitting together with VS Code open: group by group, precedence table, examples you can run immediately, common patterns, gotchas, and when to prefer which style.
1. Quick Overview – All Operator Groups in Go
| Priority (highest first) | Group | Operators | Associativity | Notes / Special in Go |
|---|---|---|---|---|
| 1 | Primary / postfix | x() x.y x[y] x[y:z] x[y:z:w] | left-to-right | slice expressions too |
| 2 | Unary | +x -x !x ^x &x *x <-x ++x –x | right-to-left | <- only for channels |
| 3 | Multiplicative | * / % << >> & &^ | left-to-right | &^ = bit clear |
| 4 | Additive | + – |
^ | left-to-right |
| 5 | Comparison | == != < <= > >= | — | No chaining like Python |
| 6 | Logical AND | && | left-to-right | short-circuit |
| 7 | Logical OR | |
||
| 8 | Channel send / receive | <- (as binary) | right-to-left | rare outside goroutines |
| 9 | Assignment / compound assign | = += -= *= /= %= <<= >>= &= |
= ^= &^= | right-to-left |
Important Go rules:
- No operator overloading (unlike C++/Python)
- No ternary ?: operator — use if-else
- No &&= or ||= compound logical operators
- Comparison operators do not chain (a < b < c is invalid)
2. Detailed Examples by Group (Copy-Paste & Run)
Create 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 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
package main import "fmt" func main() { a := 17 b := 5 c := true d := false // ──────────────────────────────────────────────── // Arithmetic (+ - * / %) // ──────────────────────────────────────────────── fmt.Println("Arithmetic:") fmt.Printf("%d + %d = %d\n", a, b, a+b) // 22 fmt.Printf("%d - %d = %d\n", a, b, a-b) // 12 fmt.Printf("%d * %d = %d\n", a, b, a*b) // 85 fmt.Printf("%d / %d = %d\n", a, b, a/b) // 3 (integer division!) fmt.Printf("%d %% %d = %d\n", a, b, a%b) // 2 (remainder) // Floating point needs float operands f1, f2 := 17.0, 5.0 fmt.Printf("%.2f / %.2f = %.2f\n", f1, f2, f1/f2) // 3.40 // ──────────────────────────────────────────────── // Bitwise (& | ^ << >> &^) // ──────────────────────────────────────────────── x, y := 0b1010, 0b1100 // 10 and 12 in binary fmt.Printf("Bitwise:\n") fmt.Printf("%04b & %04b = %04b (%d)\n", x, y, x&y, x&y) // 1000 = 8 fmt.Printf("%04b | %04b = %04b (%d)\n", x, y, x|y, x|y) // 1110 = 14 fmt.Printf("%04b ^ %04b = %04b (%d)\n", x, y, x^y, x^y) // 0110 = 6 (XOR) fmt.Printf("%04b &^ %04b = %04b (%d)\n", x, y, x&^y, x&^y) // 0010 = 2 (AND NOT) // Shifts fmt.Printf("%d << 2 = %d (%04b)\n", x, x<<2, x<<2) // 40 101000 fmt.Printf("%d >> 1 = %d (%04b)\n", y, y>>1, y>>1) // 6 0110 // ──────────────────────────────────────────────── // Comparison (== != < <= > >=) // ──────────────────────────────────────────────── fmt.Println("\nComparisons:") fmt.Println("a == b →", a == b) // false fmt.Println("a != b →", a != b) // true fmt.Println("a > b →", a > b) // true // fmt.Println(a < b < 10) // ERROR – no chaining // Strings compare lexicographically (byte by byte) fmt.Println(`"apple" < "banana" →`, "apple" < "banana") // true // ──────────────────────────────────────────────── // Logical (&& || !) // ──────────────────────────────────────────────── fmt.Println("\nLogical:") fmt.Println("c && d →", c && d) // false fmt.Println("c || d →", c || d) // true fmt.Println("!c →", !c) // false // Short-circuit evaluation (very important!) ptr := &a // if ptr != nil && *ptr > 0 { ... } // safe – if ptr==nil, second part skipped // ──────────────────────────────────────────────── // Increment / Decrement (statements, not expressions) // ──────────────────────────────────────────────── i := 10 i++ // i = 11 // j = i++ // ERROR – postfix ++ is statement only fmt.Println("i after ++ →", i) // ──────────────────────────────────────────────── // Assignment & Compound assignment // ──────────────────────────────────────────────── x = 20 x += 5 // x = 25 x &= 0b1111 // x = 9 (25 & 15) fmt.Println("x after compound ops →", x) // No power operator → use math.Pow } |
3. Very Important Go-Specific Behaviors
-
Integer division truncates toward zero 17 / 5 = 3, -17 / 5 = -3 (not -4 like some languages)
-
No automatic promotion You must convert types explicitly for mixed operations
Go0123456789var i int = 10var f float64 = 3.14// result := i + f // ERRORresult := float64(i) + f // ok -
Bit clear &^ (unique to Go) a &^ b = bits of a with bits of b turned off
Go01234567flags := 0b1111 // 15flags &^= 0b0010 // turn off bit 1 → 1101 = 13 -
No ** power operator Use math.Pow or repeated multiplication for integers
-
Logical operators short-circuit Very useful for safe pointer / nil checks
Go0123456if user != nil && user.IsActive() { ... } // safe
4. Your Quick Practice Exercise
Try to write expressions for these:
- Check if a number is even and positive
- Toggle the 3rd bit (0-indexed) of a number using bitwise operators
- Safely divide two integers and check for division by zero
- Compare two strings ignoring case (hint: use strings.ToLower)
Which operators did you use most?
Questions now?
- Precedence confusion in complex expressions?
- Bitwise tricks for flags / masks?
- How operators work with custom types later (methods)?
- Or ready for control structures (if, for, switch) next?
Keep typing these examples — operators are the glue that holds almost every logic together. You’re building a really solid foundation step by step. 💪🇮🇳 Let’s keep going! 🚀
