Jednou ze skvělých věcí na Go jsou gorutiny, pomocí kterých zajišťuje concurrency. A aby vše fungovalo jak má, potřebujete nějak synchronizovat zpracovávaná data mezi jednotlivými gorutinami.
A právě k tomu se hodí kanály, channels. Kanály jsou jeden z prostředků jazyka, jak řídit flow mezi rádoby paralelně prováděnými částmi aplikacemi, gorutinami.
Díky kanálům pak můžete naplnit jeden z konceptů Go Do not communicate by sharing memory; instead, share memory by communicating.
A věřte nebo ne, i na úrovni práce s channels pak najdete nějaké návrhové vzory:
Fan out
Z jednoho vstupního kanálu multiplikujete výstup do více výstupních kanálů:
func Fanout(In <-chan int, OutA, OutB, OutC chan int) { for data := range In { select { case OutA <- data: case OutB <- data: case OutC <- data: } } }
Fan In
Spojujete více vstupních kanálů do jednoho výstupního.
func fanIn(input1, input2 <-chan string) <-chan string { c := make(chan string) go func() { for { select { case s := <-input1: c <- s case s := <-input2: c <- s } } }() return c }
Closing channel
Closing a channel indicates that no more values will be sent on it. This can be useful to communicate completion to the channel’s receivers
package main import "fmt" func main() { jobs := make(chan int, 5) done := make(chan bool) go func() { for { j, more := <-jobs if more { fmt.Println("received job", j) } else { fmt.Println("received all jobs") done <- true return } } }() for j := 1; j <= 3; j++ { jobs <- j fmt.Println("sent job", j) } close(jobs) fmt.Println("sent all jobs") <-done }
Ve zkratce...
Uvedl jsem 3 asi nejpoužívanější channles návrhové vzory. Nicméně představivosti se meze nekladou a je jen na vás, jak skrze kanály zajistíte flow control vaší aplikace.
Další info najdete přímo na Golang blogu.