Variables
A variable is a named storage slot that holds a value. Every variable has a type, which controls the kind of value it can hold and the operations you can perform on it.
In Go, a type is a label like int (whole numbers), string (text), or bool (true or false). It determines how much space a value takes in memory and what you can do with it. The core built-in types and how they differ are covered in later lessons.
Go gives you two ways to declare a variable: a long form with the var keyword, and a short form with := that infers the type from the value you assign.
The var form
The long form is explicit. You write var, a name, a type, and an optional initial value:
var greeting string = "Hello"
All three parts (type, =, value) are optional after the name, which gives you three useful shapes:
var a int = 10 // type and value
var b = 10 // value only, type inferred
var c int // type only, value is the zero value
Variables declared using the var keyword can be declared at the top level of a file (outside any function). But the short form := is only allowed inside functions.
The short form :=
Inside a function, you will usually reach for the short form instead:
name := "Kamran"
The compiler looks at the right-hand side, sees a string literal, and gives name the type string. You never write string explicitly; Go fills it in.
Two rules for :=:
- It only works inside functions. You cannot use
:=at the top level of a file. - The left-hand side must contain at least one new name. Using
:=with only existing variables is a compile error.
Here is the error case first:
package main
import "fmt"
func main() {
x := 1
y := 2
fmt.Println(x, y)
x, y := 3, 4 // error: no new variables on left side of :=
}
Once x and y already exist, pure reassignment uses plain = instead:
x, y = 3, 4
If at least one name is new, := is allowed:
x, z := 5, 6
That last form is useful in practice: when one of the values on the right is new to scope, you can mix it with existing names and still use :=.
Inside a function, reach for := by default. It is shorter, the type is still obvious from the right-hand side, and it is what you will see in almost every real Go program. Use var when you need the zero value (no initial assignment), when you want to document the type explicitly because the value is not self-explanatory, or when you are declaring at the top level of a file where := is not allowed.
Zero values
Every type in Go has a zero value: the value a variable takes when you declare it without assigning anything. int is 0, float64 is 0, string is "", bool is false. There is no "uninitialised" or "undefined" state; a freshly declared variable is always safe to read.
var n int // n is 0
var s string // s is ""
var active bool // active is false
This is a deliberate design choice. In languages like C, reading an uninitialised local variable is a classic source of confusing bugs. Go avoids that whole category by making every variable start in a useful state.
Declaring several variables at once
Both forms let you declare more than one variable on a single line:
x, y := 1, 2
var a, b int = 10, 20
Names go on the left, values on the right, commas between. The number of names must match the number of values, and the types must match whichever side has them.
A nice consequence: you can swap two variables in one statement without a temporary variable.
x, y = y, x
fmt.Println(x, y) // 2 1
Notice that this uses plain = rather than :=, because x and y already exist and pure reassignment is not a declaration.
Scope: where a variable lives
A variable only exists inside the region of code where it is declared. The two scopes you meet first are package scope (also called file-level or top-level) and function scope:
package main
import "fmt"
var greeting = "Hello" // package scope, visible to every function in this file
func main() {
name := "Kamran" // function scope, visible only inside main
fmt.Println(greeting, name)
}
greeting is declared at the top of the file, outside any function, so main can see it. name is declared inside main function, so it only exists while main is running; no other function in the file can reach it.
A narrower kind of scope, block scope, is created every time you open a { } block inside a function (for example, inside an if or a for). Those come up in the next chapter and follow the same "only visible inside the block" rule.
Go does not let you declare a variable and then never use it. Writing unused := 42 in a function without ever referencing unused is a compile error.
The editor on this site is lenient about this, but running go build locally will reject the same code. Delete the variable or start using it.
Declare three variables and print them on one line using fmt.Println:
count, anint, usingvarwith no initial value (so it takes the zero value0)name, astring, using:=, set to"Kamran"active, abool, using:=, set totrue
0 Kamran true