channel's zero value is nil, you have to make a chan like
a := make(chan int) # this gives an unbuffered channel
// read from channel a
data := <- a
// write to channel a
a <- data
Sends and receives are blocking by default (if the channel is unbuffered)
a buffered channel is made by giving capacity in make statement
a := make(chan int, 10) (does not block till the capacity is full)
using channels, go routines can communicate
// here, done can be used to send and receive
func hello(done chan bool) { }
// here, done can be used to send and receive
func hello() done chan bool { }
// here, done can be only used to receive
func hello(done <-chan bool) { }
// here, done can be only used to send
func hello(done chan<- bool) { }
// returns a chan which can only be used to read from
func hello() done <-chan bool { }
// returns a chan which can only be used to send data to
func hello() done chan<- bool { }
channel is a first class member of the language, means you can have a chan which can take any other type or chan itself
// chanchan is a channel which has chan struct{}
chanchan := make(chan chan struct{})
ch := make(chan struct{})
close(ch)
when a channel is closed, the readers receives nil (?), to check if a chan is closed while reading we can pass the secod argument
v, ok := <- ch
if ok {
// consume v
}
A channel can be iterated using forr
the above check is done by for range
, means when a chan is closed forr ends
for v := range ch {
}
closing a channel is the responsibility of creator
https://play.golang.org/p/XLb6llJAJd
package main
import (
"fmt"
)
func digits(number int) <-chan int {
dchnl := make(chan int)
go func() {
defer close(dchnl)
for number != 0 {
digit := number % 10
dchnl <- digit
number /= 10
}
}()
return dchnl
}
func calcSquares(number int) <-chan int {
squareop := make(chan int)
go func() {
defer close(squareop)
sum := 0
dch := digits(number)
for digit := range dch {
sum += digit * digit
}
squareop <- sum
}()
return squareop
}
func calcCubes(number int) <-chan int {
cubeop := make(chan int)
sum := 0
dch := digits(number)
go func() {
defer close(cubeop)
for digit := range dch {
sum += digit * digit * digit
}
cubeop <- sum
}()
return cubeop
}
func main() {
number := 589
sqrch := calcSquares(number)
cubech := calcCubes(number)
squares, cubes := <-sqrch, <-cubech
fmt.Println("Final output", squares+cubes)
}
Lot of literature exists on go routines, channels, patterns. Watch rob pike's videos or follow go developers, read source https://github.com/lclarkmichalek/etcdhcp