A quick-reference instruction sheet covering the fundamentals of Go (Golang) programming.
Go (also called Golang) is a statically typed, compiled language created at Google. It is designed for simplicity, fast compilation, and built-in concurrency support.
.go extensionpackage; executable programs use package maingo build; run directly with go run main.gopackage main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
Compile and run:
go run main.go
go build -o myapp main.go // produces a binary
./myapp
fmt (I/O), math, strings, strconv, os, errors, net/http.// var declaration — explicit type
var name string = "Alice"
var age int = 30
var price float64 = 9.99
var active bool = true
// Short variable declaration — type inferred (inside functions only)
city := "NYC"
count := 10
// Multiple assignment
x, y := 1, 2
// Zero values — Go initialises all variables
var i int // 0
var s string // ""
var b bool // false
// Constants
const Pi = 3.14159
const Max = 100
| Type | Description | Zero value |
|---|---|---|
int, int8/16/32/64 | Signed integers | 0 |
uint, uint8/16/32/64 | Unsigned integers | 0 |
float32, float64 | Floating-point numbers | 0 |
string | Immutable UTF-8 text | "" |
bool | Boolean | false |
byte | Alias for uint8 | 0 |
rune | Alias for int32 — Unicode code point | 0 |
a, b := 10, 3
a + b // 13
a - b // 7
a * b // 30
a / b // 3 — integer division
a % b // 1 — modulus
// Comparison
a == b // false
a != b // true
a < b // false
a > b // true
// Logical
a > 5 && b < 5 // true — AND
a > 5 || b > 5 // true — OR
!(a == b) // true — NOT
// Assignment shortcuts
a += 5
a++ // increment (statement only, not expression)
++ and -- are statements, not expressions — you cannot write x = a++.import (
"fmt"
"strings"
"strconv"
)
first := "Alice"
last := "Smith"
// Concatenation
first + " " + last // "Alice Smith"
// Sprintf — formatted string (like printf but returns a string)
fmt.Sprintf("Hello, %s! Age: %d", first, 30)
// Raw string literal — backticks, no escape processing
path := `C:\Users\Alice`
// strings package
strings.ToUpper("hello") // "HELLO"
strings.ToLower("HELLO") // "hello"
strings.TrimSpace(" hi ") // "hi"
strings.Contains("hello", "ell") // true
strings.HasPrefix("hello", "he") // true
strings.Replace("aaa", "a", "b", 2) // "bba"
strings.Split("a,b,c", ",") // ["a","b","c"]
strings.Join([]string{"a","b"}, "-") // "a-b"
// Convert between strings and numbers
strconv.Itoa(42) // "42"
strconv.Atoi("42") // 42, nil
var a [3]int = [3]int{10, 20, 30}
a[0] // 10
len(a) // 3
fruits := []string{"apple", "banana", "cherry"}
fruits[0] // "apple"
fruits[1:3] // ["banana","cherry"] — slice of slice
len(fruits) // 3
cap(fruits) // underlying array capacity
fruits = append(fruits, "date") // append — may allocate new array
// Make a slice with length and capacity
s := make([]int, 5) // [0,0,0,0,0]
s := make([]int, 3, 10) // length 3, capacity 10
// Copy
dst := make([]int, len(src))
copy(dst, src)
ages := map[string]int{
"Alice": 30,
"Bob": 25,
}
ages["Alice"] // 30
ages["Carol"] = 28 // add / update
delete(ages, "Bob") // remove key
// Safe lookup — ok is false if key missing
val, ok := ages["Dave"]
if !ok {
fmt.Println("not found")
}
// Make an empty map
m := make(map[string]int)
score := 75
if score >= 90 {
fmt.Println("A")
} else if score >= 75 {
fmt.Println("B")
} else {
fmt.Println("C or below")
}
// if with initialiser — x is scoped to the if block
if x := compute(); x > 10 {
fmt.Println(x)
}
// No fallthrough by default — no break needed
switch day {
case "Mon":
fmt.Println("Monday")
case "Fri", "Sat":
fmt.Println("End of week")
default:
fmt.Println("Other")
}
// switch with no condition — acts like if/else chain
switch {
case score >= 90:
fmt.Println("A")
case score >= 75:
fmt.Println("B")
}
for. It covers all looping patterns.for i := 0; i < 5; i++ {
fmt.Println(i)
}
i := 0
for i < 5 {
fmt.Println(i)
i++
}
fruits := []string{"apple", "banana", "cherry"}
for i, fruit := range fruits {
fmt.Printf("%d: %s\n", i, fruit)
}
// Ignore index with _
for _, fruit := range fruits {
fmt.Println(fruit)
}
// Range over a map
for key, val := range ages {
fmt.Printf("%s: %d\n", key, val)
}
break to exit a loop and continue to skip to the next iteration.// Basic function
func greet(name string) string {
return "Hello, " + name + "!"
}
// Multiple return values — idiomatic Go
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf("cannot divide by zero")
}
return a / b, nil
}
result, err := divide(10, 3)
if err != nil {
fmt.Println("Error:", err)
}
// Variadic function
func sum(nums ...int) int {
total := 0
for _, n := range nums {
total += n
}
return total
}
sum(1, 2, 3, 4) // 10
// Function as a value / closure
double := func(n int) int { return n * 2 }
double(5) // 10
// defer — run at end of the surrounding function
defer fmt.Println("cleanup") // runs when function returns
error as the last return value is the standard Go pattern for error handling — there are no exceptions.// Define a struct
type Person struct {
Name string
Age int
}
// Create instances
p1 := Person{Name: "Alice", Age: 30}
p2 := Person{"Bob", 25} // positional (order matters)
p1.Name // "Alice"
p1.Age = 31 // update field
// Pointer to struct
ptr := &p1
ptr.Age = 32 // Go auto-dereferences
// Method — function with a receiver
func (p Person) Describe() string {
return fmt.Sprintf("%s is %d years old.", p.Name, p.Age)
}
// Pointer receiver — can modify the struct
func (p *Person) Birthday() {
p.Age++
}
fmt.Println(p1.Describe()) // Alice is 32 years old.
p1.Birthday() // p1.Age is now 33
An interface defines a set of method signatures. Any type that implements all the methods satisfies the interface — no explicit declaration needed.
type Shape interface {
Area() float64
Perimeter() float64
}
type Circle struct { Radius float64 }
type Rect struct { W, H float64 }
func (c Circle) Area() float64 { return math.Pi * c.Radius * c.Radius }
func (c Circle) Perimeter() float64 { return 2 * math.Pi * c.Radius }
func (r Rect) Area() float64 { return r.W * r.H }
func (r Rect) Perimeter() float64 { return 2*(r.W+r.H) }
// Both Circle and Rect satisfy Shape
func printArea(s Shape) {
fmt.Printf("Area: %.2f\n", s.Area())
}
printArea(Circle{Radius: 5})
printArea(Rect{W: 4, H: 6})
interface{} (or any in Go 1.18+) accepts any type.Go has built-in concurrency via goroutines (lightweight threads) and channels (typed message-passing pipes).
import (
"fmt"
"time"
)
func say(msg string) {
for i := 0; i < 3; i++ {
fmt.Println(msg)
time.Sleep(100 * time.Millisecond)
}
}
func main() {
go say("world") // launches a goroutine
say("hello") // runs in the main goroutine
}
func main() {
// Create a channel of ints
ch := make(chan int)
// Send a value in a goroutine
go func() {
ch <- 42 // send
}()
val := <-ch // receive (blocks until value arrives)
fmt.Println(val) // 42
}
// Buffered channel — send doesn't block until buffer is full
ch := make(chan int, 5)
// WaitGroup — wait for multiple goroutines to finish
import "sync"
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
wg.Add(1)
go func(n int) {
defer wg.Done()
fmt.Println(n)
}(i)
}
wg.Wait() // blocks until all goroutines call Done()