Skip to main content

Go Operators

Introduction

Operators are special symbols that tell the compiler to perform specific mathematical, relational, or logical operations. Go provides a rich set of operators to manipulate variables and values. Understanding operators is fundamental to writing effective Go code as they form the building blocks of expressions and statements.

In this tutorial, we'll explore the various operators available in Go, learn how to use them, and see practical examples of their applications in real-world scenarios.

Types of Operators in Go

Go supports several types of operators:

  1. Arithmetic Operators
  2. Comparison (Relational) Operators
  3. Logical Operators
  4. Bitwise Operators
  5. Assignment Operators
  6. Miscellaneous Operators

Let's dive into each category.

Arithmetic Operators

Arithmetic operators are used to perform mathematical operations like addition, subtraction, multiplication, and division.

OperatorDescriptionExample
+Additiona + b
-Subtractiona - b
*Multiplicationa * b
/Divisiona / b
%Modulus (remainder)a % b
++Incrementa++
--Decrementa--

Example: Arithmetic Operators

go
package main

import "fmt"

func main() {
a := 15
b := 4

// Addition
fmt.Printf("%d + %d = %d", a, b, a+b)

// Subtraction
fmt.Printf("%d - %d = %d", a, b, a-b)

// Multiplication
fmt.Printf("%d * %d = %d", a, b, a*b)

// Division
fmt.Printf("%d / %d = %d", a, b, a/b)

// Modulus
fmt.Printf("%d %% %d = %d", a, b, a%b)

// Increment
c := a
c++
fmt.Printf("%d++ = %d", a, c)

// Decrement
d := a
d--
fmt.Printf("%d-- = %d", a, d)
}

Output:

15 + 4 = 19
15 - 4 = 11
15 * 4 = 60
15 / 4 = 3
15 % 4 = 3
15++ = 16
15-- = 14
note

In Go, ++ and -- are statements, not expressions. This means you cannot use them in expressions like a = b++ or a = ++b. They must be used as standalone statements: a++ or b--.

Integer Division vs. Floating-Point Division

When dividing two integers in Go, the result is also an integer, with any decimal part truncated.

go
package main

import "fmt"

func main() {
// Integer division
fmt.Println("5 / 2 =", 5/2) // Outputs: 2

// Floating-point division
fmt.Println("5.0 / 2.0 =", 5.0/2.0) // Outputs: 2.5
}

Output:

5 / 2 = 2
5.0 / 2.0 = 2.5

Comparison Operators

Comparison operators are used to compare two values. They return a boolean result (true or false).

OperatorDescriptionExample
==Equal toa == b
!=Not equal toa != b
<Less thana < b
>Greater thana > b
<=Less than or equal toa <= b
>=Greater than or equal toa >= b

Example: Comparison Operators

go
package main

import "fmt"

func main() {
a := 10
b := 20

fmt.Printf("%d == %d: %t", a, b, a == b)
fmt.Printf("%d != %d: %t", a, b, a != b)
fmt.Printf("%d < %d: %t", a, b, a < b)
fmt.Printf("%d > %d: %t", a, b, a > b)
fmt.Printf("%d <= %d: %t", a, b, a <= b)
fmt.Printf("%d >= %d: %t", a, b, a >= b)
}

Output:

10 == 20: false
10 != 20: true
10 < 20: true
10 > 20: false
10 <= 20: true
10 >= 20: false

Logical Operators

Logical operators are used to combine conditional statements.

OperatorDescriptionExample
&&Logical ANDa && b
||Logical ORa || b
!Logical NOT!a

Example: Logical Operators

go
package main

import "fmt"

func main() {
a := true
b := false

// Logical AND
fmt.Printf("%t && %t = %t", a, b, a && b)

// Logical OR
fmt.Printf("%t || %t = %t", a, b, a || b)

// Logical NOT
fmt.Printf("!%t = %t", a, !a)
fmt.Printf("!%t = %t", b, !b)
}

Output:

true && false = false
true || false = true
!true = false
!false = true

Short-Circuit Evaluation

Go uses short-circuit evaluation for logical operators. This means that in an expression like a && b, if a is false, b is not evaluated because the result is already determined.

go
package main

import "fmt"

func main() {
// Short-circuit with &&
x := 10
if x > 20 && x/0 == 0 { // The second condition won't be evaluated
fmt.Println("This won't execute")
} else {
fmt.Println("Short-circuit prevented division by zero")
}

// Short-circuit with ||
y := 30
if y > 20 || y/0 == 0 { // The second condition won't be evaluated
fmt.Println("y is greater than 20")
}
}

Output:

Short-circuit prevented division by zero
y is greater than 20

Bitwise Operators

Bitwise operators perform operations on the binary representations of numbers.

OperatorDescriptionExample
&Bitwise ANDa & b
|Bitwise ORa | b
^Bitwise XORa ^ b
&^Bit clear (AND NOT)a &^ b
<<Left shifta << n
>>Right shifta >> n

Example: Bitwise Operators

go
package main

import "fmt"

func main() {
a := 60 // 00111100 in binary
b := 13 // 00001101 in binary

fmt.Printf("a = %d (%08b)", a, a)
fmt.Printf("b = %d (%08b)", b, b)

// Bitwise AND
fmt.Printf("a & b = %d (%08b)", a&b, a&b)

// Bitwise OR
fmt.Printf("a | b = %d (%08b)", a|b, a|b)

// Bitwise XOR
fmt.Printf("a ^ b = %d (%08b)", a^b, a^b)

// Bitwise AND NOT (bit clear)
fmt.Printf("a &^ b = %d (%08b)", a&^b, a&^b)

// Left shift
fmt.Printf("a << 2 = %d (%08b)", a<<2, a<<2)

// Right shift
fmt.Printf("a >> 2 = %d (%08b)", a>>2, a>>2)
}

Output:

a = 60 (00111100)
b = 13 (00001101)
a & b = 12 (00001100)
a | b = 61 (00111101)
a ^ b = 49 (00110001)
a &^ b = 48 (00110000)
a << 2 = 240 (11110000)
a >> 2 = 15 (00001111)

Practical Uses of Bitwise Operators

Bitwise operators are often used for:

  1. Flag manipulation: Setting, checking, and clearing flags in a single integer.
  2. Permissions: Managing access permissions (read, write, execute).
  3. Color manipulation: Extracting RGB components from color values.
  4. Performance optimization: Faster calculations for certain operations.

Example: Using Bitwise Operators for Flags

go
package main

import "fmt"

const (
READ = 1 << 0 // 001 in binary
WRITE = 1 << 1 // 010 in binary
EXECUTE = 1 << 2 // 100 in binary
)

func main() {
// Create permission
var permission byte = READ | WRITE // 011 in binary

// Check permissions
fmt.Printf("Permission: %08b", permission)
fmt.Printf("Has READ: %v", (permission & READ) != 0)
fmt.Printf("Has WRITE: %v", (permission & WRITE) != 0)
fmt.Printf("Has EXECUTE: %v", (permission & EXECUTE) != 0)

// Add execute permission
permission = permission | EXECUTE
fmt.Printf("After adding EXECUTE: %08b", permission)

// Remove write permission
permission = permission &^ WRITE
fmt.Printf("After removing WRITE: %08b", permission)
}

Output:

Permission: 00000011
Has READ: true
Has WRITE: true
Has EXECUTE: false
After adding EXECUTE: 00000111
After removing WRITE: 00000101

Assignment Operators

Assignment operators are used to assign values to variables.

OperatorDescriptionExampleEquivalent to
=Simple assignmenta = ba = b
+=Add and assigna += ba = a + b
-=Subtract and assigna -= ba = a - b
*=Multiply and assigna *= ba = a * b
/=Divide and assigna /= ba = a / b
%=Modulus and assigna %= ba = a % b
<<=Left shift and assigna <<= ba = a << b
>>=Right shift and assigna >>= ba = a >> b
&=Bitwise AND and assigna &= ba = a & b
^=Bitwise XOR and assigna ^= ba = a ^ b
|=Bitwise OR and assigna |= ba = a | b

Example: Assignment Operators

go
package main

import "fmt"

func main() {
a := 10

// Simple assignment
b := a
fmt.Printf("b = a: %d", b)

// Add and assign
a += 5
fmt.Printf("a += 5: %d", a)

// Subtract and assign
a -= 3
fmt.Printf("a -= 3: %d", a)

// Multiply and assign
a *= 2
fmt.Printf("a *= 2: %d", a)

// Divide and assign
a /= 4
fmt.Printf("a /= 4: %d", a)

// Modulus and assign
a %= 2
fmt.Printf("a %%= 2: %d", a)
}

Output:

b = a: 10
a += 5: 15
a -= 3: 12
a *= 2: 24
a /= 4: 6
a %= 2: 0

Miscellaneous Operators

Go also provides a few other operators that don't fit into the categories above.

OperatorDescriptionExample
&Address operator (returns the memory address)&a
*Pointer operator (dereferences a pointer)*a
<-Channel receive operatorx <- ch

Example: Address and Pointer Operators

go
package main

import "fmt"

func main() {
a := 10

// Get the memory address of a
ptr := &a
fmt.Printf("Address of a: %p", ptr)

// Access the value using the pointer
fmt.Printf("Value at address %p: %d", ptr, *ptr)

// Modify the value using the pointer
*ptr = 20
fmt.Printf("After modification, a = %d", a)
}

Output:

Address of a: 0xc000018030
Value at address 0xc000018030: 10
After modification, a = 20

Operator Precedence

Operators in Go follow a specific precedence order, which determines the order of evaluation in expressions.

PrecedenceOperators
5 (highest)*, /, %, <<, >>, &, &^
4+, -, |, ^
3==, !=, <, <=, >, >=
2&&
1 (lowest)||

Example: Operator Precedence

go
package main

import "fmt"

func main() {
// Expression: 10 + 5 * 2
result1 := 10 + 5*2
// Multiplication (*) has higher precedence than addition (+)
// So it's evaluated as: 10 + (5 * 2) = 10 + 10 = 20
fmt.Printf("10 + 5 * 2 = %d", result1)

// Using parentheses to change precedence
result2 := (10 + 5) * 2
// Now it's evaluated as: (10 + 5) * 2 = 15 * 2 = 30
fmt.Printf("(10 + 5) * 2 = %d", result2)

// Complex expression
result3 := 5 + 10*2 - 5/2 > 10 && 6%3 == 0
fmt.Printf("5 + 10*2 - 5/2 > 10 && 6%%3 == 0 = %t", result3)
}

Output:

10 + 5 * 2 = 20
(10 + 5) * 2 = 30
5 + 10*2 - 5/2 > 10 && 6%3 == 0 = true

Real-World Examples

Example 1: Calculating Sales Tax

go
package main

import "fmt"

func main() {
// Calculate sales tax on a purchase
itemPrice := 49.99
taxRate := 0.07 // 7%

taxAmount := itemPrice * taxRate
totalPrice := itemPrice + taxAmount

fmt.Printf("Item price: $%.2f", itemPrice)
fmt.Printf("Tax rate: %.0f%%", taxRate*100)
fmt.Printf("Tax amount: $%.2f", taxAmount)
fmt.Printf("Total price: $%.2f", totalPrice)
}

Output:

Item price: $49.99
Tax rate: 7%
Tax amount: $3.50
Total price: $53.49

Example 2: Temperature Conversion

go
package main

import "fmt"

func main() {
// Convert between Celsius and Fahrenheit
celsius := 25.0
fahrenheit := (celsius * 9/5) + 32

fmt.Printf("%.1f°C = %.1f°F", celsius, fahrenheit)

// Convert back to Celsius
newCelsius := (fahrenheit - 32) * 5/9
fmt.Printf("%.1f°F = %.1f°C", fahrenheit, newCelsius)
}

Output:

25.0°C = 77.0°F
77.0°F = 25.0°C

Example 3: Bit Manipulation for RGB Colors

go
package main

import "fmt"

func main() {
// Store RGB color in a single integer (0xRRGGBB)
// Red: 255 (0xFF), Green: 128 (0x80), Blue: 64 (0x40)
rgb := (255 << 16) | (128 << 8) | 64
fmt.Printf("RGB Color: 0x%06X", rgb)

// Extract individual components
red := (rgb >> 16) & 0xFF
green := (rgb >> 8) & 0xFF
blue := rgb & 0xFF

fmt.Printf("Red: %d (0x%02X)", red, red)
fmt.Printf("Green: %d (0x%02X)", green, green)
fmt.Printf("Blue: %d (0x%02X)", blue, blue)

// Modify just the green component
newGreen := 200
rgb = (rgb & 0xFF00FF) | (newGreen << 8)
fmt.Printf("New RGB Color: 0x%06X", rgb)
}

Output:

RGB Color: 0xFF8040
Red: 255 (0xFF)
Green: 128 (0x80)
Blue: 64 (0x40)
New RGB Color: 0xFFC840

Common Mistakes and Best Practices

Pitfall 1: Integer Division

One common mistake is forgetting that division between integers in Go results in an integer.

go
package main

import "fmt"

func main() {
// This will truncate the decimal part
result := 5 / 2
fmt.Println("5 / 2 =", result) // Outputs: 2

// To get a floating-point result, at least one operand must be a float
correctResult := 5.0 / 2
fmt.Println("5.0 / 2 =", correctResult) // Outputs: 2.5
}

Pitfall 2: Pre/Post Increment/Decrement

Go only has post-increment and post-decrement, not pre-increment or pre-decrement.

go
package main

import "fmt"

func main() {
a := 5

// This works
a++
fmt.Println("After a++:", a)

// This doesn't work in Go
// ++a // Syntax error: unexpected ++, expecting expression

// Also, increment and decrement are statements, not expressions
// b := a++ // Error: a++ used as value
}

Pitfall 3: Short-Circuit Evaluation Side Effects

Be careful when relying on short-circuit evaluation for side effects.

go
package main

import "fmt"

func main() {
x := 5
y := 10

// This condition modifies x only if y > 5
if y <= 5 || (x = x + 5) > 0 {
fmt.Println("Condition met")
}

// x might not be modified due to short-circuit evaluation
fmt.Println("x =", x)
}

Operator Cheat Sheet

TypeOperatorsDescription
Arithmetic+Addition
-Subtraction
*Multiplication
/Division
%Modulus (remainder)
++Increment
--Decrement
Comparison==Equal to
!=Not equal to
<Less than
>Greater than
<=Less than or equal to
>=Greater than or equal to
Logical&&Logical AND
||Logical OR
!Logical NOT
Bitwise&Bitwise AND
|Bitwise OR
^Bitwise XOR
&^Bit clear (AND NOT)
<<Left shift
>>Right shift
Assignment=Simple assignment
+=Add and assign
-=Subtract and assign
*=Multiply and assign
/=Divide and assign
%=Modulus and assign
<<=Left shift and assign
>>=Right shift and assign
&=Bitwise AND and assign
^=Bitwise XOR and assign
|=Bitwise OR and assign
Miscellaneous&Address operator
*Pointer operator
<-Channel receive/send

Summary

In this tutorial, we explored the various operators in Go:

  • Arithmetic operators perform mathematical operations like addition, subtraction, multiplication, and division.
  • Comparison operators compare values and return boolean results.
  • Logical operators combine conditional statements.
  • Bitwise operators manipulate the binary representations of numbers.
  • Assignment operators assign values to variables, sometimes performing operations first.
  • Miscellaneous operators include address, pointer, and channel operations.

We also learned about operator precedence, which determines the order of evaluation in expressions, and explored real-world applications of Go operators.

Understanding operators is fundamental to writing effective Go code, as they form the building blocks of expressions and statements. By mastering operators, you'll be able to write more concise, efficient, and powerful Go programs.

Exercises

To solidify your understanding of Go operators, try these exercises:

  1. Write a program that takes two integers as input and displays the results of all arithmetic operations on them.

  2. Create a function that converts a temperature from Celsius to Fahrenheit and vice versa using the formula: F = (C × 9/5) + 32.

  3. Write a program that calculates the total price of items in a shopping cart, including sales tax.

  4. Create a bitmap using bitwise operators to represent a set of permissions (read, write, execute) and write functions to set, clear, and check permissions.

  5. Write a program that uses bitwise operations to pack three single-digit numbers into a single integer and then extract them.

Additional Resources



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)