Syntax, Values & Types
Real programs hold values - a name, a count, a price - and do things with them. In Go, every value has a type, and the language is strict about it in a way that feels heavy at first but becomes a safety net fast.
What "statically typed" actually means
Go is statically typed: every variable has a fixed type, known and checked when your code is compiled, before it ever runs. A variable holding a number can never later hold text - the compiler verifies this up front.
Coming from Python or JavaScript, you might expect a variable to be a box you can drop anything into. In
Go it's a box with a shape - number-shaped, text-shaped - and the compiler checks everything you put in
fits. Bugs like "I thought this was a number but it was the text '42'" can't survive to runtime; they're
caught while you build.
📝 Terminology. A type is the kind of value something is - an integer, a piece of text, a true/false. Static means "checked at compile time" (vs. dynamic, "checked while running"). Go checks early, so the running program never has to wonder what type something is.
var - the explicit way to declare a value
The full, spelled-out way to create a variable uses the var keyword:
package main
import "fmt"
func main()
$ go run main.go
Ada is 36
var name string = "Ada" reads left to right as "declare a variable called name, of type string
(text), and set it to "Ada"." Same for age, of type int. fmt.Println printed all three pieces with
a space between each - the types are written right there, so there's no ambiguity about what each box
holds.
Go can usually figure the type out from the value, so you can drop it and let the compiler infer it:
var name = "Ada" // Go sees "Ada" is text, so name is a string
var age = 36 // Go sees 36 is a whole number, so age is an int
name is still a string, age still an int - you just didn't spell it out. The variable is no less
typed; the compiler inferred it.
:= - the short declaration you'll use most
Inside a function, Go gives you an even shorter form that declares and assigns at once:
package main
import "fmt"
func main()
name := "Ada" is the short variable declaration. The := means "create a new variable and set it" -
Go infers the type from the value, exactly like var name = "Ada" but more compact. This is the form
you'll see and write most in real Go code.
⚠️ Gotcha - := only works inside functions. At the top level of a file, you must use var.
Writing count := 0 outside a function is a compile error: := is shorthand for a local working
variable, and the top level is for declaring package-level things, var's job. Rule of thumb:
inside func → :=; outside → var.
The basic types you'll actually use
These cover almost everything early on:
int- a whole number, positive or negative (-3,0,42). Your default for counting.float64- a number with a decimal point (3.14,-0.5). The64is how many bits it uses; the normal choice for fractional numbers.string- text, written in double quotes ("hello").bool- a truth value, eithertrueorfalse. Named after George Boole.
There are more (smaller and larger integers, an unsigned variety, a single-character rune), but reach
for those only with a specific reason. int, float64, string, and bool will take you a long way.
Zero values - why Go variables are never "undefined"
In some languages, a variable you declare but don't set holds garbage, or a null/undefined that blows
up the moment you touch it. Go refuses to leave a variable empty. Every type has a defined zero
value, and a freshly declared variable starts there automatically.
package main
import "fmt"
func main()
$ go run main.go
0 0 false
Four variables, none set, yet all start at sensible, predictable values: int at 0, float64 at 0,
string at "" (the blank gap between 0 and false in the output), bool at false. Nothing is
"undefined" - you can read any of them immediately without a crash.
💡 Key point. The zero value rule means there is no uninitialized-variable surprise in Go. Declare
var count int and you know it's 0 - a whole class of "why is this null?" bugs never happens. Worth
memorizing: numbers → 0, strings → "", bools → false. (We'll meet nil - the zero value for a few
special types - in phase 3; it follows the same rule.)
The other unused-thing error: declared and not used
You met unused imports in phase 1. Variables have the same rule: declare one and never read it, and Go won't compile.
package main
func main()
$ go run main.go
./main.go:4:2: declared and not used: total
total was never used, so the compiler stopped and pointed at it (main.go:4:2). Fix: use the variable
(print it, return it, calculate with it) or delete the line - same philosophy as unused imports.
Printing properly with Println and Printf
You've been using fmt.Println, which prints its arguments with spaces between them and a trailing
newline - great for quick output. For control over the format, reach for fmt.Printf ("print
formatted"):
package main
import "fmt"
func main()
$ go run main.go
Ada is 36 years old.
Printf takes a format string with verbs - placeholders starting with % - filled in by the values
that follow, in order. %s means "put a string here," %d means "put a whole number (a decimal
integer) here," and \n is the newline character (Printf, unlike Println, doesn't add one for you).
Verbs worth knowing now:
%s- a string%d- an integer%f- a float (%.2frounds to 2 decimal places)%v- any value in its default form (the helpful catch-all when you're not sure)%t- a boolean (true/false)
⚠️ Gotcha. Mismatched verbs don't crash Go - it prints a visible complaint right in the output, like
%!d(string=Ada), meaning "you asked for a %d integer but handed me the string Ada." Ugly on
purpose, so you spot the mismatch instantly instead of shipping wrong output.
Recap
- Go is statically typed: every variable has a fixed type, checked when you compile.
var name type = valueis the explicit declaration; drop the type to let Go infer it.:=declares-and-assigns in one step and is what you'll use most - but only inside functions; usevarat the top level.- The everyday types:
int,float64,string,bool. - Zero values mean nothing is ever uninitialized: numbers
0, strings"", boolsfalse. - Unused variables are compile errors (
declared and not used), just like unused imports. fmt.Printlnfor quick output;fmt.Printfwith verbs (%s %d %f %v %t) for formatted output.
Next: from single values to collections - arrays, the slices you'll actually use, and maps for looking things up by name.
← Phase 1: Install & Your First Program · Guide overview · Phase 3: Collections →
Before the quiz: without looking back, say (or jot down) the core idea of this phase in your own words.
Check your understanding 3 questions
1. Go being statically typed means...
2. A 'zero value' in Go means...
3. The short declaration `:=` can be used...