# Go cheatsheet

## Command Line

go build
go run
go test


## Loop Syntax

for { // forever loop
}

for condition {
}

for i, value := range slice { // works for maps too
}

for i:=0; i<N; i++ {
}


## Slices Syntax

fibonacci := [10]int{0, 1, 1, 2, 3, 5, 8, 13, 21, 34}
var slice []int = fibonacci[3:7] // takes indexes 3, 4, 5, 6
slice2 := make([]int, 5)
fmt.Println(slice) // [2 3 5 8]

slice[0] = 1337        // note: slices are references!
fmt.Println(fibonacci) // [0, 1, 1, 1337, 3, 5, 8, 13, 21, 34]

slice = append(slice, element, ...)


## Map syntax

myMap := make(map[string]float32)

myMap["Accel"] = 9.81

// (0.0, false) if no "gyro" field; (val, true) otherwise
rate, has_field := myMap["Gyro"]


## Object Oriented-like things

### Adding methods to structs

• (v Vector3) is known as a receiver, it copies the data
• (v *Vector3) is a pointer receiver, and is useful when we will modify the struct
type Vector3 struct {
X, Y, Z float64
}
func (v *Vector3) Norm() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y + v.Z*v.Z)
}
func (v *Vector3) Add(a float64) {
v.X += a
v.Y += a
v.Z += a
}
distance = Vector3{1.0, 2.0, 3.0}.Norm()


### Interfaces

Interface implementation is implicit, if a struct has the interface’s method signatures, it implements the interface.

type Vector interface {
Norm() float64
}

var v Vector
v3 := Vector3{0.0, 0.0, 0.0}
v := &v3


Type assertions allow us to check the underlying type of something whcih meets an interface:

val, ok := v.(Vector3) // ok = true
val, ok := v.(int32)   // ok = false


Type switches:

switch v := i.(type) {
case Vector3:
// ...
case Vector2:
// ...
default:
// ...
}


## Concurrency

Run a go routine

func doSomething() {
}
go doSomething()


### Channels

ch := make(chan float64)
ch := make(chan float64, 100) // buffer 100 entries

ch <- value // send to channel
value := <- ch  // receive from channel

func doSomething(ch chan float64)

close(ch) // closes the channel

value, ok := <- ch // ok = false if ch is closed

// loop until the channel closes
for value  := range ch {
}

select { // blocks until one of its case can be run
case ch1 <- x: // runs when we can load data into c
case <-ch2:    // runs when ch2 has data
}

select { // non-blocking
case ch1 <- x: // runs when we can load data into c
case <-ch2:    // runs when ch2 has data
default:       // runs if nothing is ready
}

time.Tick(Duration)  // periodic channel
time.After(Duration) // periodic channel


## Enums

Use iota:

type Commands int

const (
Sit Commands = iota
Fetch
RollOver
)


This stack exchange answer details some more advanced techniques including bitfield enumeration.

Categories:

Updated: