Variables & Types

Master Go's type system — declarations, basic types, zero values, constants, and type conversions.

Beginner 30 min read 🐹 Go

Variable Declarations

Go is statically typed — every variable has a fixed type determined at compile time. Unlike Go, Golang, you can't change a variable's type after declaration. Go offers several ways to declare variables:

var and := (Short Declaration)

package main

import "fmt"

func main() {
    // var with explicit type
    var name string = "Alice"
    var age int = 30

    // var with type inference
    var city = "NYC"  // Go infers string

    // Short declaration (most common inside functions)
    score := 95.5     // Go infers float64
    active := true    // Go infers bool

    fmt.Println(name, age, city, score, active)

    // Multiple declarations
    var x, y, z int = 1, 2, 3
    a, b := "hello", 42

    fmt.Println(x, y, z, a, b)
}
Output
Alice 30 NYC 95.5 true
1 2 3 hello 42

Use := inside functions (it's shorter and idiomatic). Use var for package-level variables or when you want an explicit type. := cannot be used outside functions.

Key Takeaway: := declares AND assigns. = only assigns (variable must already exist). This is the most common Go beginner confusion.

Basic Types

TypeDescriptionExampleZero Value
boolBooleantrue, falsefalse
stringUTF-8 string"hello"""
intInteger (platform-sized)420
int8/16/32/64Sized integersint64(100)0
uintUnsigned integeruint(42)0
float32/64Floating point3.140.0
byteAlias for uint8'A'0
runeAlias for int32 (Unicode)'你'0

Zero Values

Go doesn't have null, undefined, or None. Instead, every type has a zero value — the default value when a variable is declared without initialization:

var i int       // 0
var f float64   // 0.0
var b bool      // false
var s string    // "" (empty string)
var p *int      // nil (pointers, interfaces, slices, maps, channels)

fmt.Printf("int: %d, float: %f, bool: %t, string: %q\n", i, f, b, s)
Output
int: 0, float: 0.000000, bool: false, string: ""

Zero values prevent bugs

In Go, you can always safely use a variable's zero value. An empty string, 0, or false is always valid. This eliminates entire classes of null pointer bugs that plague Java, C, and even Python.

Constants

const Pi = 3.14159
const MaxRetries = 3

// Constant block
const (
    StatusOK    = 200
    StatusNotFound = 404
    StatusError = 500
)

// iota — auto-incrementing constant generator
const (
    Sunday = iota  // 0
    Monday         // 1
    Tuesday        // 2
    Wednesday      // 3
)

fmt.Println(Sunday, Monday, Tuesday, Wednesday)
Output
0 1 2 3

Type Conversions

Go has no implicit type conversions. You must explicitly convert between types, even between int and float64:

var i int = 42
var f float64 = float64(i)    // int to float64
var u uint = uint(f)          // float64 to uint

// String conversions
import "strconv"
s := strconv.Itoa(42)        // int to string: "42"
n, _ := strconv.Atoi("42")   // string to int: 42
f, _ := strconv.ParseFloat("3.14", 64)  // string to float64

⚠️ Common Mistake: string(42) doesn't do what you think

Wrong:

s := string(42)  // "*" (Unicode code point 42), NOT "42"!

Why: string() converts an integer to its Unicode character, not its string representation.

Instead:

s := strconv.Itoa(42)       // "42"
s := fmt.Sprintf("%d", 42) // "42"
🔍 Deep Dive: Why No Implicit Conversions?

Go requires explicit conversions to prevent subtle bugs. In C, int x = 3.7 silently truncates to 3. In JavaScript, "5" + 3 gives "53". Go refuses to guess. If you want to convert, you must say so explicitly. This makes code more readable and prevents an entire category of type-related bugs.

Practice Exercises

Easy Hello World Variant

Modify the example to accept user input and print a personalized greeting.

Easy Code Reading

Read through the code examples above and predict the output before running them.

Medium Extend the Example

Take one code example and add error handling, input validation, or a new feature.