So far every statement in your programs ran, every time. Real programs choose: a different message for a different age, a discount only above a certain total. This lesson shows how a Go program decides what to do. You have already used one decision, if err != nil; now you will see how it works.
Conditions are true or false
A condition is an expression whose value is either true or false. Those two values have a type of their own, called bool (short for "boolean", after the mathematician George Boole).
The most common conditions compare two values:
| Written | Meaning |
|---|---|
a == b |
a is equal to b |
a != b |
a is not equal to b |
a < b |
a is less than b |
a > b |
a is greater than b |
a <= b |
a is less than or equal to b |
a >= b |
a is greater than or equal to b |
package main
import "fmt"
func main() {
age := 20
fmt.Println(age >= 18)
fmt.Println(age == 21)
fmt.Println("tea" != "coffee")
}This prints true, false and true.
Take care with the two signs that look alike. A single = assigns a value to a variable. A double == asks a question: are these two equal?
Both sides of a comparison must have the same type. Comparing a whole number with a string is refused by the compiler, which is one more reason to convert typed text into a number first.
if runs a block only when its condition is true
package main
import "fmt"
func main() {
temperature := 31
if temperature > 30 {
fmt.Println("It is hot today.")
fmt.Println("Drink some water.")
}
fmt.Println("Have a good day.")
}This prints all three lines. Change 31 to 20 and run it again: only Have a good day. is printed.
The statements between the curly brackets after if are called a block. When the condition is true, the whole block runs. When it is false, Go skips the block and carries on after the closing curly bracket. The last line is outside the block, so it runs either way.
Two rules about the shape:
- The condition sits between
ifand the opening curly bracket. It needs no round brackets around it. - The opening curly bracket must be on the same line as the
if.
else gives the other path
else adds a second block that runs when the condition is false. Exactly one of the two blocks runs, never both and never neither.
package main
import "fmt"
func main() {
age := 15
if age >= 18 {
fmt.Println("You can vote.")
} else {
fmt.Println("You cannot vote yet.")
}
}This prints You cannot vote yet.. The word else must be on the same line as the closing curly bracket before it: } else {.
else if chooses between several paths
To choose between more than two paths, put else if with another condition between the first block and the final else.
package main
import "fmt"
func main() {
age := 9
if age < 5 {
fmt.Println("Free")
} else if age < 16 {
fmt.Println("Child ticket")
} else {
fmt.Println("Adult ticket")
}
fmt.Println("Enjoy your visit.")
}This prints Child ticket and then Enjoy your visit..
Go asks the conditions in order, from the top. The first one that is true has its block run, and then the rest of the chain is skipped, even if a later condition would also have been true. The else block runs only when every condition above it was false.
age := 9 the first condition is false, the second is true, and its block runs. Go then skips the rest of the chain and carries on below it.Because the conditions are asked in order, each one can rely on the ones above it having been false. On line 9 there is no need to write "5 or more and under 16": reaching that line already means the age is not under 5.
else catches everything that is left.Combining conditions
Three signs build a bigger condition out of smaller ones:
a && b("and") is true only when both sides are true.a || b("or") is true when at least one side is true.!a("not") turns true into false and false into true.
package main
import "fmt"
func main() {
age := 10
height := 135
if age >= 8 && height >= 120 {
fmt.Println("You can ride.")
}
if age < 5 || age >= 65 {
fmt.Println("Free entry.")
} else {
fmt.Println("Entry costs 4.")
}
}This prints You can ride. and then Entry costs 4.. Both sides of && are true, so the first block runs. Neither side of || is true, so the else block runs.
Write each side as a complete comparison. "Age between 5 and 12" is age >= 5 && age <= 12; Go does not understand 5 <= age <= 12.
Decisions about what the user typed
You can now read the pattern from the last lesson in full. strconv.Atoi gives back a number and an error value, and if err != nil asks "is the error value something other than nothing?". When it is, the block prints a message and return ends the program.
This program reads two numbers and then decides:
package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
fmt.Print("Price? ")
scanner.Scan()
price, err := strconv.Atoi(scanner.Text())
if err != nil {
fmt.Println("Please type a whole number.")
return
}
fmt.Print("Money in your pocket? ")
scanner.Scan()
money, err := strconv.Atoi(scanner.Text())
if err != nil {
fmt.Println("Please type a whole number.")
return
}
if money >= price {
fmt.Println("You can buy it. Change:", money-price)
} else {
fmt.Println("You need", price-money, "more.")
}
}With the answers 12 and 20 the session is:
Price? 12
Money in your pocket? 20
You can buy it. Change: 8Notice money, err := .... In the last lesson you saw that := needs something new on its left. Here err already exists, but money is new, and one new name is enough: Go creates money and reuses err.
Try the program in the playground with two lines in the Standard input box, then with 20 and 12.
Three errors you will meet
One = where two are needed.
package main
import "fmt"
func main() {
age := 20
if age = 18 {
fmt.Println("Exactly eighteen")
}
}# command-line-arguments
./main.go:7:12: syntax error: cannot use assignment age = 18 as valueA syntax error means the text breaks the writing rules of the language. age = 18 is an assignment, not a question, so it has no true-or-false value for if to use. Write age == 18.
The opening curly bracket on its own line.
package main
import "fmt"
func main() {
age := 20
if age >= 18
{
fmt.Println("You can vote.")
}
}# command-line-arguments
./main.go:7:17: syntax error: unexpected newline, expected { after if clauseThe message says what Go expected to find at the end of line 7: the {. The same rule is behind } else {: put else on a line of its own and the compiler reports syntax error: unexpected keyword else, expected }.
A number where a condition is needed.
package main
import "fmt"
func main() {
count := 3
if count {
fmt.Println("There are some.")
}
}# command-line-arguments
./main.go:7:8: non-boolean condition in if statementIn Go a condition must be a bool: true or false. A number is neither. Say what you mean with a comparison: if count > 0 {.
What you can do now
You can compare values, choose between two or more blocks with if, else if and else, combine conditions with &&, || and !, and explain the error check you have been writing since the last lesson. In the exercises you will follow values through chains, repair two wrong decisions and write the program for a theme-park ride.
Next: repeat steps with for, so that a program can do something many times without your writing it many times.