Go Syntax & Variables

Packages, the main function, variables, zero values, and Go's built-in types.

Package and imports

Go
package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println(strings.ToUpper("hello"))
}

Go groups multiple imports in one import ( ... ) block by convention, and gofmt will reformat single imports into this form for you as the file grows.

Declaring variables

Go
var name string = "Qaisar"   // explicit type
var age = 21                 // type inferred from the value
count := 0                   // short declaration — infers int, only valid inside functions

var (
    width  = 100
    height = 50
)

:= is the idiomatic way to declare and initialize a variable inside a function body. var is used at package level, or when you want to declare without initializing.

Zero values

Unlike Java or C, Go always initializes variables to a sane zero value — there's no "uninitialized garbage memory":

Type Zero value
int, float64 0
string "" (empty string)
bool false
pointers, slices, maps, interfaces nil
Go
var count int      // 0
var label string    // ""
var enabled bool    // false
fmt.Println(count, label, enabled) // 0  false

Built-in types

Go
var i int        = 42
var f float64     = 3.14
var s string      = "hello"
var b bool        = true
var r rune        = 'A'   // a Unicode code point (int32 under the hood)
var by byte       = 255   // alias for uint8

Constants

Go
const Pi = 3.14159
const MaxRetries = 3

Arrays and slices

Arrays have a fixed size baked into their type; slices (dynamically-sized views over an array) are what you use almost everywhere in idiomatic Go:

Go
var arr [3]int = [3]int{1, 2, 3}   // fixed size: 3

nums := []int{1, 2, 3}             // a slice — dynamically sized
nums = append(nums, 4)             // append returns a (possibly reallocated) slice
fmt.Println(nums)                  // [1 2 3 4]
fmt.Println(len(nums))             // 4

subset := nums[1:3]                // slicing: elements at index 1 and 2
fmt.Println(subset)                // [2 3]

Maps

Go
ages := map[string]int{
    "Ali":   22,
    "Bilal": 25,
}

ages["Zara"] = 19            // insert/update
value, exists := ages["Ali"] // "comma ok" idiom — check existence safely
fmt.Println(value, exists)   // 22 true

delete(ages, "Bilal")

String formatting with fmt

Go
name := "Ali"
age := 22
fmt.Printf("%s is %d years old\n", name, age)     // Sprintf-style formatting
message := fmt.Sprintf("%s is %d", name, age)      // returns a string instead of printing

Common mistakes

  • Declaring a variable with := and never using it — Go treats unused local variables as a compile error, not a warning.
  • Confusing arrays ([3]int, fixed size, part of the type) with slices ([]int, dynamic, what you almost always want).
  • Ignoring the second return value from a map lookup (value, exists := m[key]) and mistaking a zero value for a missing key.

Interview questions

Q: What is a Go "zero value" and why does the language guarantee it? Every declared-but-uninitialized variable automatically gets a predictable default (0, "", false, nil) rather than leftover memory garbage — this eliminates an entire class of undefined-behaviour bugs common in languages like C.

Q: What's the difference between an array and a slice in Go? An array has a fixed length that's part of its type ([3]int and [5]int are different types). A slice is a lightweight, resizable view over an underlying array, and is what idiomatic Go code uses almost exclusively.