Go Syntax & Variables
Packages, the main function, variables, zero values, and Go's built-in types.
Package and imports
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
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 |
var count int // 0
var label string // ""
var enabled bool // false
fmt.Println(count, label, enabled) // 0 false
Built-in types
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
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:
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
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
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.