Understanding Operators in Go Programming
Go provides a comprehensive set of operators for performing various operations. This guide covers all the operators available in Go and how to use them effectively.
Arithmetic Operators
Basic Arithmetic
// Addition
sum := 5 + 3 // 8
// Subtraction
diff := 10 - 5 // 5
// Multiplication
product := 4 * 3 // 12
// Division
quotient := 15 / 3 // 5
quotient = 10 / 3 // 3 (integer division)
// Modulus (remainder)
remainder := 10 % 3 // 1
// Increment
x := 5
x++ // x is now 6
// Decrement
x-- // x is now 5
Compound Assignment
x := 10
// Add and assign
x += 5 // x = x + 5
// Subtract and assign
x -= 3 // x = x - 3
// Multiply and assign
x *= 2 // x = x * 2
// Divide and assign
x /= 4 // x = x / 4
// Modulus and assign
x %= 3 // x = x % 3
Comparison Operators
x, y := 10, 20
// Equal to
isEqual := x == y // false
// Not equal to
notEqual := x != y // true
// Greater than
isGreater := x > y // false
// Less than
isLess := x < y // true
// Greater than or equal to
isGreaterEqual := x >= y // false
// Less than or equal to
isLessEqual := x <= y // true
Logical Operators
p, q := true, false
// Logical AND
result := p && q // false
// Logical OR
result = p || q // true
// Logical NOT
result = !p // false
// Short-circuit evaluation
if p && someExpensiveFunction() {
// someExpensiveFunction is not called if p is false
}
if p || someExpensiveFunction() {
// someExpensiveFunction is not called if p is true
}
Bitwise Operators
x, y := 12, 25 // 1100, 11001 in binary
// Bitwise AND
result := x & y // 8 (1000)
// Bitwise OR
result = x | y // 29 (11101)
// Bitwise XOR
result = x ^ y // 21 (10101)
// Bitwise NOT
result = ^x // -13 (complement)
// Left shift
result = x << 2 // 48 (110000)
// Right shift
result = x >> 2 // 3 (11)
Address Operators
// Address of operator
x := 42
ptr := &x // Get address of x
// Dereference operator
value := *ptr // Get value at address
// Example with pointers
func increment(ptr *int) {
*ptr++ // Increment value at address
}
num := 10
increment(&num) // Pass address of num
Channel Operators
// Channel send operator
ch := make(chan int)
ch <- 42 // Send value to channel
// Channel receive operator
value := <-ch // Receive from channel
// Select with channel operations
select {
case v := <-ch1:
// Handle value from ch1
case ch2 <- value:
// Send value to ch2
default:
// No channel ready
}
Operator Precedence
// Operator precedence (highest to lowest)
result := 5 + 3 * 2 // 11 (not 16)
result = (5 + 3) * 2 // 16
// Complex expressions
result = 15 - 3 * 2 + 4/2 // 11
// Bitwise operations
result = 5 | 3 & 2 // 7
result = (5 | 3) & 2 // 0
Best Practices
1. Clear Expressions
// Good: Clear and readable
result := (a + b) * (c + d)
// Avoid: Complex nested operations
result = a + b * c + d / e % f
2. Type Safety
// Good: Type-safe operations
var (
i int = 42
f float64 = float64(i) * 2.5
)
// Avoid: Implicit conversions
f = i * 2.5 // Compilation error
3. Pointer Safety
// Good: Check for nil pointers
func process(ptr *int) {
if ptr == nil {
return
}
*ptr++
}
// Avoid: Unchecked pointer dereference
func unsafe(ptr *int) {
*ptr++ // Panic if ptr is nil
}
Common Patterns
1. Bit Manipulation
// Set bit
flag := flag | (1 << position)
// Clear bit
flag := flag &^ (1 << position)
// Toggle bit
flag := flag ^ (1 << position)
// Check bit
isSet := (flag & (1 << position)) != 0
2. Integer Division
// Round towards zero (default)
result := 10 / 3 // 3
// Round up
result = (10 + 2) / 3 // 4
// Round down
result = 10 / 3 // 3
3. Safe Division
func safeDivide(x, y float64) (float64, error) {
if y == 0 {
return 0, errors.New("division by zero")
}
return x / y, nil
}
Performance Considerations
1. Arithmetic Operations
// Multiplication vs Shift
result := x * 2 // Less readable
result = x << 1 // More efficient
// Division vs Shift
result = x / 2 // Less readable
result = x >> 1 // More efficient (for positive numbers)
2. Boolean Operations
// Short-circuit evaluation
if expensive() && cheap() { // Bad: expensive always runs
// ...
}
if cheap() && expensive() { // Good: expensive may be skipped
// ...
}
Common Mistakes
1. Integer Overflow
// Wrong: Possible overflow
var x int32 = 2147483647
x++ // Overflow
// Right: Check for overflow
if x < math.MaxInt32 {
x++
}
2. Division by Zero
// Wrong: Possible panic
result := x / y // Panics if y is 0
// Right: Check for zero
if y != 0 {
result = x / y
} else {
// Handle division by zero
}
Next Steps
- Learn about control flow
- Explore functions
- Study error handling
- Practice with data types