Booleans
tally should print extra detail when the user adds -v. That is a yes-or-no question, and Go answers yes-or-no questions with exactly one type, bool. Go is stricter about it than most languages — and that strictness removes a whole family of bugs.
The rule
A condition is a bool — nothing else counts — and
&&,||stop early.
A bool holds true or false, and its zero value is false. You get one from a literal, a comparison, or the logic operators:
verbose := false
long := len(word) > 7 // comparison: true or false
ok := long && !verbose // and, not
either := long || verbose // orNo truthiness. In some languages 0, "" or an empty list count as false. In Go they do not count at all:
if len(words) { } // compile error: non-boolean condition
if len(words) > 0 { } // fineThere is also no conversion between bool and numbers: int(true) does not compile. Say what you mean with a comparison.
Short-circuit. a && b does not evaluate b when a is false; a || b does not evaluate b when a is true. That makes guards possible:
verbose := len(os.Args) > 2 && os.Args[2] == "-v"If there are only two arguments, the right side is never run, so os.Args[2] never panics.
Printing uses %t or plain Println, which shows true or false. Turning text into a bool uses strconv.ParseBool("true").
The shortcut
For every && or ||, put the cheap, safe check on the left and the risky one on the right. Then read left to right and stop the moment the answer is settled.
Left side
len(os.Args) > 2is2 > 2: false.
Swap the sides and the same input panics before the length check ever runs.
Drills
Answer fast — trust the rule.
What is the zero value of a bool?
Which condition compiles?
a := false. In a && expensive(), how many times does expensive run?
What does fmt.Println(3 > 2 || 1/zero == 0) print, where zero is an int variable holding 0?
Remember
- A condition is a bool — nothing else counts — and
&&,||stop early. - Shortcut: cheap, safe check on the left; risky check on the right.
- Trap: truthiness habits from other languages do not compile in Go.
