Variables and zero values
Programs need to remember things: a price, how many items, a test score. A variable is a named box that holds a value.
1package main2 3import "fmt"4 5func main() {6 var price int = 257 count := 48 fmt.Println("Price:", price, "Count:", count)9 fmt.Println("Total:", price*count)10}
Price: 25 Count: 4 Total: 100
var price int = 25 means: give me a box for a whole number (int), call it price, and put 25 in it. count := 4 is a shorter way to write the same kind of thing; more on it below.
var and :=
var score int declares a variable: it tells the compiler there is a variable that holds whole numbers. score = 80 assigns to it: it puts a value in the box, and the old value is gone.
:= declares and assigns in one step, and the value on the right decides the type: in bonus := 10, 10 is a whole number, so bonus is an int. You can only use := inside a function, and only the first time; after that, change the variable with =.
1package main2 3import "fmt"4 5func main() {6 var score int7 score = 808 fmt.Println(score)9 bonus := 1010 score = score + bonus11 fmt.Println(score)12}
80 90
Press Step and watch score go from 0 to 80, then to 90.
Zero values
You may have noticed while stepping: right after var score int, score already holds 0. In Go, a variable you declare without a value doesn't hold "whatever was there". It holds the zero value of its type:
1package main2 3import "fmt"4 5func main() {6 var count int7 var price float648 var name string9 var done bool10 fmt.Println(count, price, done)11 fmt.Println("Name is [" + name + "]")12}
0 0 false Name is []
The zero value of whole numbers and decimals is 0, of a string it's the empty string "" (nothing between the square brackets), and of a bool it's false. + joins two strings into a longer one.
Four everyday types
| Type | Holds | Examples |
|---|---|---|
int | whole numbers | 30, -5 |
float64 | decimals | 1.75, 36.6 |
string | text | "Paris" |
bool | true or false | true, false |
With := you don't write the type. To see which type Go picked, use %T with fmt.Printf:
1package main2 3import "fmt"4 5func main() {6 age := 307 height := 1.758 city := "Paris"9 member := true10 fmt.Printf("%T\n", age)11 fmt.Printf("%T\n", height)12 fmt.Printf("%T\n", city)13 fmt.Printf("%T\n", member)14}
int float64 string bool
Printf shows things by a format: the %T in the quotes becomes the type of the value after it. Printf doesn't end the line by itself, so put \n at the end. 30 gives an int; 1.75 gives a float64.
Several at once
You can declare several variables on one line, with := or =. low, high = high, low swaps two values in one step:
1package main2 3import "fmt"4 5func main() {6 var width, height int = 3, 47 fmt.Println("Area:", width*height)8 low, high := 18, 269 fmt.Println("From", low, "to", high)10 low, high = high, low11 fmt.Println("Swapped:", low, high)12}
Area: 12 From 18 to 26 Swapped: 26 18
Constants
Some values never change: 7 days in a week, a 10% tax rate. Declare a constant with const. It can go outside the function, so the whole program can use it:
1package main2 3import "fmt"4 5const taxRate = 0.16 7func main() {8 const days = 79 price := 200.010 fmt.Println("Tax:", price*taxRate)11 fmt.Println("Two weeks:", days*2, "days")12}
Tax: 20 Two weeks: 14 days
You can't assign to a constant: add days = 8 inside main and the compiler complains. Writing 200.0 instead of 200 makes price a float64.
Types don't mix
Go never turns an int into a float64 on its own. Multiply a whole number by a decimal and the program doesn't compile:
1package main2 3import "fmt"4 5func main() {6 count := 37 price := 2.58 total := count * price9 fmt.Println(total)10}
# command-line-arguments
./prog.go:8:11: invalid operation: count * price (mismatched types int and float64)The error says count * price is not allowed: the two sides have different types, int and float64. Convert them yourself: float64(count) gives the same number as a float64, and int(price) gives an int, dropping the decimal part (it does not round):
1package main2 3import "fmt"4 5func main() {6 count := 37 price := 2.58 total := float64(count) * price9 fmt.Println(total)10 fmt.Println(int(price))11}
7.5 2
One more thing: dividing two whole numbers gives a whole number, with the decimal part dropped. % is the remainder: 17 % 5 is 2.
What does this show?
1package main2 3import "fmt"4 5func main() {6 total := 177 people := 28 fmt.Println(total / people)9}
total and people are both int, and a whole number divided by a whole number stays whole: the .5 of 8.5 is dropped, giving 8. For 8.5, write float64(total) / float64(people).
Unused variables
Lesson 1 said an unused package is a compile error. So is an unused variable:
1package main2 3import "fmt"4 5func main() {6 price := 257 discount := 58 fmt.Println(price)9}
# command-line-arguments
./prog.go:7:2: declared and not used: discount./prog.go:7:2 is line 7, character 2: discount is declared but never used. Assigning to a variable doesn't count as using it; reading it does. Delete the line or use the variable (show price - discount, say), and it runs.
Practice
Write the code, then press Check. A hint costs nothing; the answer is there when you need it.
Fix it: whole number times decimal
✓This program doesn't compile. Fix it so it shows the total for two items, Total: 50 and Total: 16.
Total: 50 Total: 16
1package main2 3import "fmt"4 5func main() {6 price := 12.57 count := 48 fmt.Println("Total:", price*count)9 price = 3.210 count = 511 fmt.Println("Total:", price*count)12}
An average with decimals
✓The program works out two students' average over four tests, but the decimals are lost. Fix it so it shows Average: 83.25 and Average: 78.
Average: 83.25 Average: 78
1package main2 3import "fmt"4 5func main() {6 a, b, c, d := 90, 85, 78, 807 fmt.Println("Average:", (a+b+c+d)/4)8 a, b, c, d = 70, 81, 95, 669 fmt.Println("Average:", (a+b+c+d)/4)10}
Splitting into groups
✓People split into groups of a fixed size. Use / and % to work out how many groups there are and how many people are left, showing 5 groups, 3 left (23 people, groups of 4) and 5 groups, 0 left (30 people, groups of 6).
5 groups, 3 left 5 groups, 0 left
1package main2 3import "fmt"4 5func main() {6 people, size := 23, 47 fmt.Println(people, size)8 people, size = 30, 69 fmt.Println(people, size)10}
What you learned
var x intdeclares a variable;x := valuedeclares and assigns, and the value decides the type; change it later with=.- A variable without a value holds its zero value: 0 for numbers,
""for strings,falseforbool. - The everyday types are
int,float64,stringandbool;fmt.Printf("%T\n", x)shows a type. constdeclares a constant, which can't change.intandfloat64don't mix: convert withfloat64(n)orint(x). Whole-number division drops the decimals, and%is the remainder.- A variable that is declared and never used is a compile error.