Skip to content

Go Language Cheat Sheet

Go (also known as Golang) is a statically typed, compiled language developed by Robert Griesemer, Rob Pike, and Ken Thompson at Google. Go’s syntax is similar to C, but it features memory safety, garbage collection (GC), structural typing, and CSP-style concurrency.

Hello world

package main

import "fmt"

func main() {
  message := greetMe("world")
  fmt.Println(message)
}

func greetMe(name string) (string) {
  return "Hello, " + name + "!"
}
$ go build

Variables

Variable declaration

var msg string
msg = "Hello"

Short-hand

msg := "Hello"

Constants

const Phi = 1.618

Constants can be characters, strings, booleans, or numeric values.

Basic Types

Strings

str := "Hello"
str := `Multiline
string`

Strings are of type string.

Numbers

Typical types

num := 3          // int
num := 3.         // float64
num := 3 + 4i     // complex128
num := byte('a')  // byte (alias for uint8)

Other types

var u uint = 7        // uint (unsigned)
var p float32 = 22.7  // 32-bit float

Pointers

func main () {
  b := *getPointer()
  fmt.Println("Value is", b)
}

func getPointer () (myPointer *int) {
  a := 234
  return &a
}

Pointers point to a memory location of a variable. Go is fully garbage collected.

Arrays

// var numbers [5]int
numbers := [...]int{0, 0, 0, 0, 0}

Arrays have a fixed size.

Slices

slice := []int{2, 3, 4}
slice := []byte("Hello")

Unlike arrays, slices have a dynamic size.

Flow Control

If Condition

if day == "sunday" || day == "saturday" {
  rest()
} else if day == "monday" && isTired() {
  groan()
} else {
  work()
}

Statements in if

if _, err := getResult(); err != nil {
  fmt.Println("Uh oh")
}

An if statement can execute a simple statement before the conditional expression.

Switch

switch day {
  case "sunday":
    // cases don't "fall through" by default!
    fallthrough

  case "saturday":
    rest()

  default:
    work()
}

Functions

Lambdas

myfunc := func() bool {
  return x > 10000
}

Functions are first-class objects.

Multiple Return Types

a, b := getMessage()
func getMessage() (a string, b string) {
  return "Hello", "World"
}

Named Return Values

func split(sum int) (x, y int) {
  x = sum * 4 / 9
  y = sum - x
  return
}

By naming return values in the declaration, return (without arguments) will return the variables with those names.

Packages

Loading

import "fmt"
import "math/rand"
import (
  "fmt"        // gives fmt.Println
  "math/rand"  // gives rand.Intn
)

Both are the same.

Alias

import r "math/rand"

r.Intn()

Exported Names

func Hello () {
  ···
}

Exported names start with a capital letter.

Packages

package hello

Every package file must start with a package statement.

Concurrency

Goroutines

func main() {
  // A "channel"
  ch := make(chan string)

  // Start concurrent routines
  go push("Moe", ch)
  go push("Larry", ch)
  go push("Curly", ch)

  // Read 3 results
  // (Since our goroutines are concurrent,
  // the order isn't guaranteed!)
  fmt.Println(<-ch, <-ch, <-ch)
}

func push(name string, ch chan string) {
  msg := "Hey, " + name
  ch <- msg
}

Channels are concurrency-safe communication objects used within goroutines.

Buffered Channels

ch := make(chan int, 2)
ch <- 1
ch <- 2
ch <- 3
// fatal error:
// all goroutines are asleep - deadlock!

Buffered channels limit the number of messages they can hold.

Closing Channels

Closes a channel

ch <- 1
ch <- 2
ch <- 3
close(ch)

Iterate over a channel until it’s closed

for i := range ch {
  ···
}

Closed if ok == false

v, ok := <- ch

Error Control

Defer

func main() {
  defer fmt.Println("Done")
  fmt.Println("Working...")
}

Defers the execution of a function until the surrounding function returns. The arguments are evaluated immediately, but the function call doesn’t run until the end.

Defer Functions

func main() {
  defer func() {
    fmt.Println("Done")
  }()
  fmt.Println("Working...")
}

Lambdas are well-suited for defer blocks.

Structs

Definition

type Vertex struct {
  X int
  Y int
}

func main() {
  v := Vertex{1, 2}
  v.X = 4
  fmt.Println(v.X, v.Y)
}

Literals

v := Vertex{X: 1, Y: 2}
// Field names can be omitted
v := Vertex{1, 2}
// Y is implicit
v := Vertex{X: 1}

Field names can optionally be specified.

Pointers to Structs

v := &Vertex{1, 2}
v.X = 2

When v is a pointer, v.X is equivalent to (*v).X.

Methods

Receiver

type Vertex struct {
  X, Y float64
}
func (v Vertex) Abs() float64 {
  return math.Sqrt(v.X * v.X + v.Y * v.Y)
}

v := Vertex{1, 2}
v.Abs()

Go doesn’t have classes, but you can define functions with receivers.

Mutating Receiver

func (v *Vertex) Scale(f float64) {
  v.X = v.X * f
  v.Y = v.Y * f
}

v := Vertex{6, 12}
v.Scale(0.5)
// `v` is updated