Skip to content

Instantly share code, notes, and snippets.

@malisetti
Last active July 24, 2017 18:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save malisetti/942fb1cb9852504981a3dc22a8d7111c to your computer and use it in GitHub Desktop.
Save malisetti/942fb1cb9852504981a3dc22a8d7111c to your computer and use it in GitHub Desktop.

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{})

closing channels

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 {
}

Note on closing a channel

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment