Variables & Constants
A variable is a named place in memory that holds a value your program can change, such as a student's marks or the items in a cart. A constant is a named value that never changes, such as the GST rate. Go gives you a few ways to create each one, and it is strict about using them.
In this lesson you will learn var and the short := form, the zero value that every Go variable starts with, and how to build simple enumerations with const and iota.
Declaring variables
The full form uses the var keyword, a name, a type and an optional starting value. Inside functions, most Go code uses the shorter := form, which works out the type from the value.
package main
import "fmt"
func main() {
var name string = "Aarav" // name, type and value
var age = 21 // type worked out from the value: int
city := "Lucknow" // short form, only inside functions
fmt.Println(name, age, city)
age = 22 // assignment: change the value, no new variable
fmt.Println("Next year:", age)
}Aarav 21 Lucknow Next year: 22
Read := as "declare and assign". Use plain = later when you only want to change the value. The type never changes: after age = 22, writing age = "twenty" is a compile error, because age is an int for its whole life.
Names in Go use camelCase: totalMarks, ticketPrice. Short names such as i, n or err are normal for variables that live only a few lines.
Zero values
In Go, a variable declared without a value is never "undefined" or full of garbage. It gets the zero value of its type:
| Type | Zero value |
|---|---|
Numbers (int, float64, ...) | 0 |
string | "" (empty string) |
bool | false |
| Pointers, slices, maps, channels, functions, interfaces | nil |
package main
import "fmt"
func main() {
var marks int
var passed bool
var nickname string
var price float64
fmt.Println(marks, passed, price)
fmt.Printf("%q\n", nickname)
}0 false 0 ""
%q prints a string in double quotes, which makes the empty string visible. Zero values are useful: a counter can start at zero without any setup, and many Go types are designed so that their zero value is ready to use.
Several variables at once
You can declare or assign several variables in one line. The right side is fully evaluated first, which gives you a neat way to swap two values without a temporary variable:
package main
import "fmt"
func main() {
batsman, runs := "Rohan", 48
fmt.Println(batsman, runs)
first, second := "Meera", "Isha"
first, second = second, first
fmt.Println(first, second)
var (
train = "Shatabdi"
coach = "C3"
seat int = 42
)
fmt.Println(train, coach, seat)
}Rohan 48 Isha Meera Shatabdi C3 42
The var ( ... ) block groups related declarations and is common at package level, outside any function, where := is not allowed.
Go's strict rules for variables
Unused variables are errors. If you declare a local variable and never read it, the program does not compile:
func main() {
total := 0
fmt.Println("hello")
}./main.go:6:2: declared and not used: total
This rule catches typos and dead code. When a function returns a value you truly do not need, assign it to the blank identifier _, which throws the value away.
:= needs at least one new name. x := 1 followed by x := 2 in the same block fails with "no new variables on left side of :=". Use x = 2.
Shadowing. A := inside an inner block creates a new variable that hides the outer one with the same name. This is a common source of bugs:
package main
import "fmt"
func main() {
fee := 500
member := true
if member {
fee := fee - 100 // new variable, only inside the if block
fmt.Println("Inside:", fee)
}
fmt.Println("Outside:", fee)
}Inside: 400 Outside: 500
The discount was lost because the inner fee disappeared at the closing brace. Writing fee = fee - 100 (plain =) changes the outer variable, so Outside: 400 would print.
Constants
Use const for values fixed when you write the program. Constants can be numbers, strings or booleans, and they must be known at compile time, so you cannot set one from a function call that runs later.
A constant written without a type is untyped. It takes whatever numeric type the situation needs, which makes constants flexible:
package main
import "fmt"
const gstPercent = 18 // untyped constant
const shopName = "Kabir Mobiles"
func main() {
var price float64 = 1299.0
tax := price * gstPercent / 100
fmt.Println(shopName)
fmt.Println("Tax:", tax)
}Kabir Mobiles Tax: 233.82
gstPercent acted as a float64 here. If it were an int variable, price * gstPercent would fail with "mismatched types float64 and int", because Go never mixes numeric types silently.
Enumerations with iota
Go has no enum keyword. Instead, inside a const block, the special word iota counts 0, 1, 2 and so on, one step per line. Lines without a value repeat the previous expression:
package main
import "fmt"
const (
Pending = iota // 0
Packed // 1
Shipped // 2
Delivered // 3
)
const (
_ = iota // skip 0
KB = 1 << (10 * iota) // 1 << 10
MB // 1 << 20
GB // 1 << 30
)
func main() {
fmt.Println(Pending, Packed, Shipped, Delivered)
fmt.Println(KB, MB, GB)
}0 1 2 3 1024 1048576 1073741824
In the second block, iota is 1 on the KB line, so 1 << 10 is 1024. The << operator shifts bits left, which multiplies by 2 for each step. In Structs & Methods you will give such constants their own type and a readable name.
Common mistakes
- Using
:=outside a function. At package level you must writevar x = 5. - Accidental shadowing with
:=insideiforforblocks, as shown above. - Expecting constants from function calls.
const today = time.Now()does not compile; use a variable. - Mixing types. An
intvariable and afloat64variable cannot be added without conversion.
Key points
var name type = valueis the full form;name := valueis the short form inside functions.- Every variable starts with its zero value:
0,"",falseornil. - Unused local variables are compile errors; use
_to discard values you do not need. :=in an inner block can shadow an outer variable; use=to change the outer one.constvalues are fixed at compile time, andiotanumbers constants in a block.
Exercise
A railway booking app needs four seat classes: Sleeper, AC3, AC2 and AC1, numbered from 1 (not 0) with iota. Declare them as constants. Then declare a variable fare with the zero value, set it to 1450, and print the class number for AC3 and the fare.
Show solution
package main
import "fmt"
const (
Sleeper = iota + 1
AC3
AC2
AC1
)
func main() {
var fare int
fmt.Println("Starting fare:", fare)
fare = 1450
fmt.Println("AC3 class number:", AC3)
fmt.Println("Fare:", fare)
}Starting fare: 0 AC3 class number: 2 Fare: 1450
Each line repeats iota + 1, so the values are 1, 2, 3 and 4. The variable starts at its zero value and is then changed with plain =.
Quick Quiz
1. What is the value of var count int before anything is assigned?
Every Go variable starts at its zero value, which is 0 for numbers.
2. Where can you use the short form x := 10?
:= is allowed only inside function bodies; package-level variables need var.
3. What does iota equal on the third line of a const block?
iota starts at 0 on the first line, so the third line gets 2.
4. What happens when you declare a local variable and never use it?
Go reports "declared and not used" as a compile error.
Learn Go with a mentor
Free lessons get you started. Our Programming & Software Development training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
