Skip to content

Go Programmeertaal Cheat Sheet

Go (ook bekend als Golang) is een statisch getypeerde, gecompileerde taal ontwikkeld door Robert Griesemer, Rob Pike en Ken Thompson bij Google. De syntaxis van Go is vergelijkbaar met C, maar bevat functies zoals geheugenveiligheid, GC (Garbage Collection), structurele typering en CSP-stijl 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

Variabelen

Variabelendeclaratie

var msg string
msg = "Hello"

Korte notatie

msg := "Hello"

Constanten

const Phi = 1.618

Constanten kunnen tekens, strings, booleaanse waarden of numerieke waarden zijn.

Basistypen

Strings

str := "Hello"
str := `Meerdere regels
string`

Het type voor strings is string.

Getallen

Typische typen

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

Andere typen

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

Pointers

func main () {
  b := *getPointer()
  fmt.Println("Waarde is", b)
}
 
func getPointer () (myPointer *int) {
  a := 234
  return &a
}

Pointers wijzen naar een geheugenlocatie van een variabele. Go heeft volledig automatisch geheugenbeheer (Garbage Collection).

Arrays

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

Arrays hebben een vaste grootte.

Slices

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

In tegenstelling tot arrays hebben slices een dynamische grootte.

Controle-structuren

Voorwaarden

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

Statement in if

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

Een if-statement kan een eenvoudig statement uitvoeren vóór de voorwaardelijke expressie.

Switch

switch day {
  case "sunday":
    // cases "vallen" standaard niet door!
    fallthrough

  case "saturday":
    rest()

  default:
    work()
}

Functies

Lambdas (anonieme functies)

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

Functies zijn “first-class objects”.

Meerdere retourtypen

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

Benoemde retourwaarden

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

Door de retourwaarden een naam te geven in de declaratie, zal return (zonder argumenten) de variabelen met die namen retourneren.

Packages

Laden

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

Beide zijn hetzelfde.

Aliassen

import r "math/rand"
 
r.Intn()

Geëxporteerde namen

func Hello () {
  ···
}

Geëxporteerde namen beginnen met een hoofdletter.

Packages

package hello

Elk package-bestand moet beginnen met een package-verklaring.

Concurrency (gelijktijdigheid)

Goroutines

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

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

  // Lees 3 resultaten
  // (Omdat onze goroutines gelijktijdig zijn,
  // is de volgorde niet gegarandeerd!)
  fmt.Println(<-ch, <-ch, <-ch)
}
 
func push(name string, ch chan string) {
  msg := "Hey, " + name
  ch <- msg
}

Channels (kanalen) zijn communicatie-objecten die veilig zijn voor gelijktijdigheid en worden gebruikt in goroutines.

Gebufferde kanalen

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

Gebufferde kanalen beperken het aantal berichten dat ze kunnen vasthouden.

Kanalen sluiten

Sluit een kanaal

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

Over een kanaal itereren totdat het gesloten is

for i := range ch {
  ···
}

Gesloten als ok == false

v, ok := <- ch

Defer & Panic

Defer

func main() {
  defer fmt.Println("Klaar")
  fmt.Println("Bezig...")
}

Stelt de uitvoering van een functie uit totdat de omringende functie terugkeert. De argumenten worden onmiddellijk geëvalueerd, maar de functie-aanroep wordt pas aan het einde uitgevoerd.

Defer met Lambdas

func main() {
  defer func() {
    fmt.Println("Klaar")
  }()
  fmt.Println("Bezig...")
}

Lambdas zijn beter voor uitgestelde blokken.

Structs

Definitie

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}
// Veldnamen kunnen worden weggelaten
v := Vertex{1, 2}
// Y is impliciet
v := Vertex{X: 1}

Je kunt ook veldnamen specificeren.

Pointers naar structs

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

Wanneer v een pointer is, zijn v.X en (*v).X hetzelfde.

Methoden

Receivers

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()

Er zijn geen klassen, maar je kunt functies op typen definiëren met behulp van receivers.

Pointer-receivers

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 bijgewerkt