Operators

Go · Lesson 8 of 32 6 min read Updated

Operators are the symbols that do work on values: + adds, == compares, && combines conditions. Most of them look like those in C, Java or JavaScript, but Go has a few rules of its own that catch people who come from other languages.

In this lesson you will use arithmetic, assignment, comparison, logical and bitwise operators, and learn Go's precedence rules and the operators Go deliberately leaves out.

Arithmetic operators

OperatorMeaningExample (a := 17, b := 5)Result
+Add (also joins strings)a + b22
-Subtracta - b12
*Multiplya * b85
/Dividea / b3
%Remaindera % b2

When both sides are integers, / is integer division: the fraction is thrown away, towards zero. The % (remainder) operator works only on integers, and its sign follows the left side.

Go
package main

import "fmt"

func main() {
	players := 17
	teamSize := 5
	fmt.Println("Full teams:", players/teamSize)
	fmt.Println("Players left over:", players%teamSize)

	loss := -17
	fmt.Println(loss/teamSize, loss%teamSize)

	distance := 7.0
	fmt.Println(distance / 2)

	fmt.Println("Ro" + "htak")
}
Output
Full teams: 3
Players left over: 2
-3 -2
3.5
Rohtak

Seventeen players make 3 full teams of five with 2 left over. With a negative number the result moves towards zero, so -17 / 5 is -3 and the remainder is -2. With a float64, / keeps the fraction.

Assignment operators and ++

Each arithmetic operator has a short assignment form: x += 5 means x = x + 5. Go also has ++ and --, but they are statements, not expressions. You can write count++ on its own line, but not total = count++ or ++count.

Go
package main

import "fmt"

func main() {
	score := 10
	score += 5  // 15
	score *= 2  // 30
	score -= 4  // 26
	score /= 3  // 8 (integer division)
	score %= 5  // 3
	score++     // 4
	fmt.Println("Final score:", score)
}
Output
Final score: 4

Making ++ a statement removes a whole family of confusing C puzzles such as i = i++ + ++i. In Go, each line does one clear thing.

Comparison and logical operators

Comparison operators (==, !=, <, <=, >, >=) produce a bool. Both sides must have the same type: comparing an int with a float64 variable is a compile error.

Logical operators combine bool values: && (and), || (or) and ! (not).

Go
package main

import "fmt"

func main() {
	age := 19
	hasVoterID := true
	marks := 72

	canVote := age >= 18 && hasVoterID
	scholarship := marks >= 90 || (marks >= 70 && age < 21)

	fmt.Println("Can vote:", canVote)
	fmt.Println("Scholarship:", scholarship)
	fmt.Println("Cannot vote:", !canVote)
}
Output
Can vote: true
Scholarship: true
Cannot vote: false

&& and || short-circuit: Go stops as soon as the answer is known. In len(names) > 0 && names[0] == "Priya", the second part runs only when the slice is not empty, so it can never crash with an index error. Put the cheap or safe check first.

Bitwise operators

Bitwise operators work on the individual bits of integers. They are common for flags and permissions:

OperatorNameEffect
&ANDBit is 1 if both bits are 1
|ORBit is 1 if either bit is 1
^XORBit is 1 if the bits differ (as a prefix, ^x flips every bit)
&^AND NOT (bit clear)Clears the bits that are set on the right
<<, >>Shift left, rightMoves bits; 1 << 3 is 8
Go
package main

import "fmt"

const (
	Read   = 1 << iota // 1 (binary 001)
	Write              // 2 (binary 010)
	Delete             // 4 (binary 100)
)

func main() {
	perm := Read | Write
	fmt.Println("perm:", perm)
	fmt.Println("can write:", perm&Write != 0)
	fmt.Println("can delete:", perm&Delete != 0)

	perm &^= Write // take away write access
	fmt.Println("after clear:", perm)
	fmt.Printf("%03b\n", Read|Delete)
}
Output
perm: 3
can write: true
can delete: false
after clear: 1
101

&^ is unique to Go: perm &^ Write keeps every bit of perm except those set in Write. The %03b verb prints a number in binary, padded to three digits.

Precedence

Go has only five precedence levels for binary operators, from highest to lowest:

  1. * / % << >> & &^
  2. + - | ^
  3. == != < <= > >=
  4. &&
  5. ||

Notice that & binds tighter than ==. That is why perm&Write != 0 above means (perm&Write) != 0. In C the opposite is true, which causes real bugs there. Use brackets whenever an expression is not obvious at a glance; gofmt even removes spaces around the tighter operators to hint at the grouping.

What Go leaves out

  • No ternary operator. There is no cond ? a : b. Write a short if:
Go
status := "Fail"
if marks >= 40 {
	status = "Pass"
}
  • No automatic type mixing. int plus float64 must be converted first.
  • No operator overloading. + on your own types is not possible; you write methods instead.

Common mistakes

  • Expecting 7 / 2 to be 3.5. Two integers give 3. Write 7.0 / 2 or convert to float64.
  • Writing x = i++. ++ is a statement in Go, so this does not compile.
  • Using ^ for powers. 2 ^ 3 is XOR (which gives 1), not 8. Use math.Pow(2, 3) or a shift such as 1 << 3.
  • Comparing different types. count == 2.5 where count is an int variable will not compile.

Key points

  • Integer / drops the fraction towards zero; % gives the remainder with the sign of the left side.
  • ++ and -- are postfix statements, not expressions.
  • && and || short-circuit, so put safety checks first.
  • Bitwise operators include Go's own &^ (bit clear); & binds tighter than ==.
  • Go has no ternary operator and never mixes numeric types automatically.

Exercise

A school bus in Lucknow carries 42 students and each van carries 9. Print how many full vans are needed, how many students are left over, and the total number of vans needed (full vans plus one more if anyone is left over). Then print whether a student aged 15 with a bus pass may travel alone, using the rule: age 14 or more AND has a pass.

Show solution
Go
package main

import "fmt"

func main() {
	students := 42
	perVan := 9

	full := students / perVan
	left := students % perVan
	vans := full
	if left > 0 {
		vans++
	}
	fmt.Println("Full vans:", full, "Left over:", left, "Vans needed:", vans)

	age := 15
	hasPass := true
	fmt.Println("May travel alone:", age >= 14 && hasPass)
}
Output
Full vans: 4 Left over: 6 Vans needed: 5
May travel alone: true

42 divided by 9 is 4 with remainder 6, so one extra van is needed. A plain if replaces the ternary operator other languages use.

Quick Quiz

1. What does 17 % 5 evaluate to in Go?

2. Which line compiles in Go?

3. What does 2 ^ 3 give in Go?

4. How does Go read flags&Write != 0?

Learn Go with a mentor

Free lessons get you started. Our Programming & Software Development training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call