Comparisons and logic
So far Go's calculator has answered with numbers. But a program constantly needs another kind of answer, "yes" or "no": whether a user is an adult, whether a number falls within a range. A comparison gives such an answer, and its result has type bool:
package main
import "fmt"
func main() {
age := 20
adult := age >= 18
teen := age >= 13 && age <= 19
fmt.Println(adult, teen) // true false
}Let's walk through the example line by line:
age := 20declares the age.adult := age >= 18holds for20, soadultistrue.teen := age >= 13 && age <= 19:age >= 13is true, but20 <= 19is not. The&&operator requires both sides to be true, soteenisfalse.fmt.Println(adult, teen)printstrue false.
Six comparison operators
Go has six comparison operators:
==is equal;!=is not equal;<is less than;<=is less than or equal;>is greater than;>=is greater than or equal.
A double == checks equality, while a single = assigns a value. Only values of the same type can be compared: for an n of type int, the expression n < 2.5 does not compile.
Logical operators
Logical operators work on values of type bool and combine several yes/no answers into one. There are three of them.
&&: AND
The expression a && b gives true only when both operands are true. If at least one of them is false, the result is false.
You use it when all conditions must hold at once. A typical example is a range check: age >= 13 && age <= 19.
||: OR
The expression a || b gives true when at least one operand is true. The result is false only when both operands are false.
You use it when any of the options will do: day == 6 || day == 7 holds for both Saturday and Sunday.
!: NOT
The ! operator goes before a single operand and turns true into false and back: !adult is true when adult is false.
! has a trap: it applies only to the nearest operand. To negate a comparison, wrap it in parentheses: !(age >= 18). Without them, !age >= 18 does not compile.
Logical operators do not accept a number in place of a bool. For an x of type int, the expression !x does not compile.
Order of evaluation
In one expression, operators run in this order:
- arithmetic:
n%2 == 0means(n%2) == 0; - comparisons;
&&;||.
&& groups its operands before || does, the way multiplication groups before addition. So a || b && c means a || (b && c). Parentheses make that order visible, and they are never wrong.
Short-circuit evaluation
Picture a bouncer at a club door. He lets a guest in if the guest has a ticket and is at least 18. If there is no ticket, the bouncer does not ask about age: the answer is "no" anyway.
&& and || behave the same way. They evaluate the left operand first. If it already settles the answer, the right operand is not evaluated at all:
&&skips its right operand when the left one isfalse;||skips its right operand when the left one istrue.
This rule is called short-circuit evaluation:
package main
import "fmt"
func isEven(n int) bool {
fmt.Print("isEven ")
return n%2 == 0
}
func main() {
fmt.Println(isEven(3) && isEven(4)) // isEven false
fmt.Println(isEven(4) || isEven(3)) // isEven true
}fmt.Print prints without a line break, so the word and the result share a line. Let's go through both lines of main:
isEven(3) && isEven(4)printsisEven false:isEven(3)returnedfalse, andisEven(4)was never called.isEven(4) || isEven(3)printsisEven true:isEven(4)returnedtrue, andisEven(3)was never called.
That is why the right operand can rely on the left one. The expression d != 0 && n/d > 2 never divides by zero.
A bouncer may start with either question, but Go may not: it always evaluates the left operand first. So the order of operands matters. Short-circuit evaluation is a common interview question: you are shown an expression with a function call to the right of && and asked what the program prints.
Common mistake
A range check is written the way it is in math:
x := 15
fmt.Println(0 < x < 10) // ✗invalid operation: 0 < x < 10 (mismatched types untyped bool and untyped int)The program does not compile. The expression reads as (0 < x) < 10: the left side becomes a bool, and a bool cannot be compared with a number. A range is checked with two comparisons: 0 < x && x < 10.
Key points
- A comparison gives a
bool;==checks equality, and=assigns. &&is true when both operands are,||when at least one is;&&groups before||.- The right operand of
&&is skipped when the left isfalse, and that of||when the left istrue. - A range is checked with two comparisons:
0 < x && x < 10.
Subscribe to take the course
The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.