Channel

Channels are used to communicate between goroutines. They are a highly effective abstraction, the clojure guys reimplemented it as core.async.

send and receive

package main

import (
	"fmt"
)

func main() {
	ch := make(chan int)

	go func() {
        fmt.Println("sending 1")
		ch <- 1
        fmt.Println("sending 2")
		ch <- 2
	}()

	fmt.Println("        receiving 1")
	fmt.Println("        received", <-ch, "receiving 2")
	fmt.Println("        received", <-ch)
}

Output:

sending 1
        receiving 1
        received 1 receiving 2
sending 2
        received 2

Or:

        receiving 1
sending 1
sending 2
        received 1 receiving 2
        received 2

buffered channel

Both send and receive are blocking operations, unless the channel is buffered.

package main

import (
	"fmt"
)

func main() {
	ch := make(chan int, 1)
	ch <- 1
	fmt.Print(<-ch)
}

close a channel

A channel should be closed, if no more values will be send to it

package main

import (
	"fmt"
)

func main() {
	ch := make(chan int)

	go func() {
		ch <- 1
		close(ch)
	}()

	val, ok := <-ch
	fmt.Println(val, ok)
	val, ok = <-ch
	fmt.Println(val, ok)
}

Output:

1 true
0 false

iterate over channel

package main

import (
	"fmt"
	"time"
)

func main() {
	ch := make(chan int)

	go func() {
		for i := range 10 {
			time.Sleep(time.Millisecond * 100)
			ch <- i
		}
		close(ch)
	}()

	for val := range ch {
		fmt.Print(val)
	}
}