Variadic Functions

func main() {
fmt.Println(adder(1, 2, 3)) // 6
fmt.Println(adder(9, 9)) // 18
nums := []int{10, 20, 30}
fmt.Println(adder(nums...)) // 60
}
// By using ... before the type name of the last parameter you can indicate that it takes zero or more of those parameters.
// The function is invoked like any other function except we can pass as many arguments as we want.
func adder(args ...int) int {
total := 0
for _, v := range args { // Iterates over the arguments whatever the number.
total += v
}
return total
}

Loops

// There's only `for`, no `while`, no `until`
for i := 1; i < 10; i++ {
}
for ; i < 10; { // while - loop
}
for i < 10 { // you can omit semicolons if there is only a condition
}
for { // you can omit the condition ~ while (true)
}

Operations on Arrays and Slices

len(a) gives you the length of an array/a slice. It's a built-in function, not a attribute/method on the array.

// loop over an array/a slice
for i, e := range a {
// i is the index, e the element
}
// if you only need e:
for _, e := range a {
// e is the element
}
// ...and if you only need the index
for i := range a {
}
// In Go pre-1.4, you'll get a compiler error if you're not using i and e.
// Go 1.4 introduced a variable-free form, so that you can do this
for range time.Tick(time.Second) {
// do it once a sec
}

Anonymous structs:
Cheaper and safer than using map[string]interface{}.

point := struct {
X, Y int
}{1, 2}

Pointers

p := Vertex{1, 2} // p is a Vertex
q := &p // q is a pointer to a Vertex
r := &Vertex{1, 2} // r is also a pointer to a Vertex
// The type of a pointer to a Vertex is *Vertex
var s *Vertex = new(Vertex) // new creates a pointer to a new struct instance

Concurrency

Goroutines

Goroutines are lightweight threads (managed by Go, not OS threads). go f(a, b) starts a new goroutine which runs f (given f is a function).

// just a function (which can be later started as a goroutine)
func doStuff(s string) {
}
func main() {
// using a named function in a goroutine
go doStuff("foobar")
// using an anonymous inner function in a goroutine
go func (x int) {
// function body goes here
}(42)
}

Channels

ch := make(chan int) // create a channel of type int
ch <- 42 // Send a value to the channel ch.
v := <-ch // Receive a value from ch
// Non-buffered channels block. Read blocks when no value is available, write blocks if a value already has been written but not read.
// Create a buffered channel. Writing to a buffered channels does not block if less than <buffer size> unread values have been written.
ch := make(chan int, 100)
close(ch) // closes the channel (only sender should close)
// read from channel and test if it has been closed
v, ok := <-ch
// if ok is false, channel has been closed
// Read from channel until it is closed
for i := range ch {
fmt.Println(i)
}
// select blocks on multiple channel operations, if one unblocks, the corresponding case is executed
func doStuff(channelOut, channelIn chan int) {
select {
case channelOut <- 42:
fmt.Println("We could write to channelOut!")
case x := <- channelIn:
fmt.Println("We could read from channelIn")
case <-time.After(time.Second * 1):
fmt.Println("timeout")
}
}