11. Variables and types
Chapter 07 wrote text directly inside fmt.Println calls.
That works, but any information needed in more than one place has to be
retyped every time. Variables fix that. A variable is a
name that stands in for a value, so you write the value once and reuse
it.
Chapters 04 and 10 showed := and = briefly.
This chapter explains them fully. As before, short examples show only
the lines that go inside main.
Declaring a variable
The most common shape of a variable declaration in Go:
name := "Keiko"
fmt.Println("Hello, " + name)Two things are going on in that first line:
nameis the variable's name. You pick it.:=declares a new variable and puts the value on the right into it. It does not mean "equal to" the way=does in maths.
Now name stands in for the string "Keiko",
so the second line prints Hello, Keiko.
Go has a longer way to write the same declaration, with the keyword
var and the type written out:
var name string = "Keiko"
fmt.Println(name)Both make the same variable. Most Go code uses := when
it has a value to start with, and var when it does not, as
you will see below.
:= only works inside a function. Outside one, Go stops
with
syntax error: non-declaration statement outside function body.
You will learn about functions in Chapter 21. For now, all your
variables live inside main.
Changing a variable
A variable's value can change. Use a plain =, which is
called assignment:
score := 0
fmt.Println(score) // prints 0
score = 50
fmt.Println(score) // prints 50:= makes a new variable and = changes one
that already exists. Mixing them up gives an error each way. Writing
score := 50 when score already exists
gives:
no new variables on left side of :=
Writing score = 50 when score does not
exist yet gives:
undefined: score
Open exercises/11/01-variables.go. Change the starting
value of score and run the file. The first
fmt.Println should change. The second still prints
50. Why?
Types
In Go every value has a type, and so does every variable. The four types you need right now:
- string — text, written between quotes:
"hello","a",""(the empty string). - int — a whole number with no decimal point:
0,-7,42. - float64 — a number with a decimal point:
3.14,0.5,-1.0. - bool — exactly two values:
trueandfalse. No quotes, and all lower case.Truewith a capital is the errorundefined: True.
When you write :=, Go works out the type from the value,
so level := 7 makes an int.
fmt.Printf has a marker that prints the type of a value:
%T.
fmt.Printf("%T\n", "hello") // string
fmt.Printf("%T\n", 7) // int
fmt.Printf("%T\n", 3.14) // float64
fmt.Printf("%T\n", true) // boolThis is exercises/11/02-types.go.
The name float64 comes from "floating point", the way
computers store numbers with decimals, and 64 is the number of bits each
one uses. Go has other number types, but int and
float64 are all this book needs for now.
Zero values
You can declare a variable with var and give it no
value. Go then fills it with the zero value of its
type:
| Type | Zero value |
|---|---|
int |
0 |
float64 |
0 |
bool |
false |
string |
"" (the empty string) |
var score int
var price float64
var alive bool
var name string
fmt.Println(score)
fmt.Println(price)
fmt.Println(alive)
fmt.Println("[" + name + "]") // the brackets show the empty stringOutput:
0
0
false
[]
This is in exercises/11/04-zero-values.go. So a Go
variable always holds a real value of its type, from the moment it is
declared.
A variable keeps its type
A variable's value can change, but its type cannot. Once
score is an int, it can only ever hold ints. The compiler
checks this before anything runs, and this checking is why Go is called
statically typed.
Open exercises/11/05-wrong-type.go. It does not compile.
The first run prints:
# command-line-arguments
exercises\11\05-wrong-type.go:11:10: cannot use "fifty" (untyped string constant) as int value in assignment
Read it in the usual order: line 11, column 10. score is
an int, and "fifty" is a string. Untyped string
constant is Go's name for a string written directly in the code.
Fix the file by assigning a number instead.
Variables must be used
Chapter 10 showed this error. Declare a variable and never read it, and the program does not compile:
name := "Keiko"
fmt.Println("hi")name declared and not used
Assigning to a variable does not count as using it. Only reading its value does, for example by printing it. If you see this error, either use the variable or delete the line.
Constants
A value that must never change can be a constant.
Write const instead of using :=:
const maxLevel = 99
fmt.Println(maxLevel) // 99Assigning to it later is an error:
const maxLevel = 99
maxLevel = 100cannot assign to maxLevel (neither addressable nor a map index expression)
The wording is unusual, but the line it names is the one that tries to change the constant. Use a constant for a fixed rule of your program, such as the highest level, so the name explains the number.
Variable names
You pick variable names, but Go has rules about which are allowed:
- They can contain letters, digits, and the underscore
_. - They cannot start with a digit.
level1is fine;1levelis not. - They are case sensitive.
Score,score, andSCOREare three different names. - They cannot be one of Go's keywords:
break,case,chan,const,continue,default,defer,else,fallthrough,for,func,go,goto,if,import,interface,map,package,range,return,select,struct,switch,type,var. You will meet most of these later.
Beyond the rules, follow these habits from Chapter 05:
- Choose meaningful names.
playerNamebeatsn.hitPointsbeatshponce code gets long, thoughhpis fine for short programs. - camelCase is the standard Go style:
maxScore,enemyCount. Start with a lower case letter, because a capital first letter has a special meaning that Chapter 25 explains.
Printing a variable
fmt.Println does not need quotes around variable names.
Quotes are only for text you type directly. To combine a label with a
variable, either pass them as separate arguments or use
fmt.Printf from Chapter 09:
level := 7
fmt.Println("Level:", level) // Level: 7
fmt.Printf("Level: %d\n", level) // Level: 7%s is for strings and %d is for whole
numbers. A third marker, %v, prints any value in its usual
form, which makes it the easy choice for a bool:
alive := true
fmt.Printf("Alive: %v\n", alive) // Alive: truefmt.Println("Level:", level) prints a space between each
argument automatically. fmt.Printf prints exactly what you
write, so you control every character. Both are correct;
fmt.Printf gives more control. Chapter 14 covers these
markers in full.
Multiple assignment
Go lets you declare several variables and give them several values on one line. Names on the left pair with values on the right by position:
name, level := "Keiko", 7
fmt.Println(name, level) // Keiko 7This groups related declarations neatly. The values can have different types, as they do here. It also enables a handy trick — swapping two variables in one step:
a, b := 1, 2
a, b = b, a
fmt.Println(a, b) // 2 1Go reads the whole right side first, then assigns. So
a, b = b, a takes the current b and
a and puts them in opposite slots. The second line uses
=, not :=, because a and
b already exist. These examples are in
exercises/11/03-multi-assignment.go.
Homework
Homework starters are in exercises/11/homework/. Each
one runs as it is and prints a placeholder line. Replace that line with
your own code. When a starter already has variables, the placeholder
line prints them too, because Go will not compile a variable nobody
reads.
Problem 1 — Player vitals
Open exercises/11/homework/01-player-vitals.go. Declare
four variables called name, level,
hitPoints, and alive, with values of your
choice. The first must be a string, the next two whole numbers, and the
fourth a bool. Print each on its own line with a label, like
Name: Keiko.
Problem 2 — Type checker
Open exercises/11/homework/02-type-checker.go. Use
fmt.Printf with %T to print the type of each
of these five values, one per line:
- the string
"world", - the whole number
42, - the decimal
3.14, - the bool
false, - the number
7.0.
Before you run it, predict the answer for the last one.
Problem 3 — Rename and reassign
Open exercises/11/homework/03-rename-and-reassign.go.
The starter file has three variables a, b, and
c with random-looking values. Rename them to something
meaningful for their values, print them with a label, change all three
to new values of the same types, then print them again.
Challenge — The zero value mystery
Open exercises/11/homework/04-zero-value-mystery.go.
Declare a string variable with var and give it no value.
Print its value between square brackets and its type with
%T. Then give it a string value and print both again. Add a
short comment block (several lines starting with //)
explaining, in your own words, what a zero value is.
Stuck or finished? Open the homework solutions page.