Go channels is the method of communication that allows go routines to talk to each other. These are FIFO. The dev has to define the type that goes into the channel. The type can be anything: structs, maps, slices, primitives, etc.
If two go routines were processes, the go channel is the bridge between them:
Non-Buffered Channels
By default channels are unbuffered, meaning that they will only accept sends (chan <-) if there is a corresponding receive (<-chan) ready to receive the sent value
1
channel:=make(chanElementType)
Buffered Channels
Buffered channels accept a limited number of values without a corresponding receiver for those values. These are much more flexible than unbuffered channels.
1
channel:=make(chanElementType,channelSize)
Reading and Writing to Channels
The <- denotes which way a value is getting written into
Writing
1
channel<-writeValue
- writeValue is getting written into channel
Reading
1
readVar<-channel
- The front of channel is getting read into declared variable readVar
Non-buffered example
A go routine is writing into nonBufferedChannel and has a receive in the main goroutine
1 2 3 4 5 6 7 8 91011121314
nonBuffedChannel:=make(chanstring)gofunc(){nonBuffedChannel<-"ping"}()fmt.Println(<-nonBuffedChannel)fmt.Println("Finished")//This will not work:messages:=make(chanstring)messages<-"no"fmt.Println(<-messages)fmt.Println("Done")
This will not run correctly because there is no immediate receiver (eg a concurrent receiver) for the send into messages
- Strings are getting written into the messages channel and read out in a FIFO way
Uni-directional Channels
A function can be configured to be able to only read from a given channel or be forced to only write into a channel. This is used for type safety, and it ensures no two go routines can write to the same channel.
Send-Only
123
funcfunctionName(sendOnlyChannelchan<-ElementType,...){//This function can only write into the given channel}
- The above function can only write data into sendOnlyChannel; it cannot read from the channel
Receive-Only
123
funcfunctionName(receiveOnlyChannel<-chanElementType,...){//This function can only read from the given channel}
- The above function can only read data from receiveOnlyChannel; it cannot write into the channel
Example:
1234
//ping fct can only write into pings channelfuncping(pingschan<-string,msgstring){pings<-msg}
123456
//pong fct can only read from pings channel and write into pongs channelfuncpong(pings<-chanstring,pongschan<-string){msg:=<-pingspongs<-msg}
The main function uses range in order to iterate through all the values in the closed factorialChannel.
Select
A goroutine that uses select waits until it has read or written to a specified channel.
Syntax:
1 2 3 4 5 6 7 8 9101112
select{//Waits until channel's front is read into readVarcasereadVar:=<-channel:...//Waits until writeVar is queued into channelcasechannel<-writeVar:...default:...}
Notes
Blocking Send/Receive: Without default, select waits until something can be read from channel or written into it
Non-Blocking Send/Receive: With default, select does not wait for a send or receive case to be satisfied
Example
1 2 3 4 5 6 7 8 91011121314151617181920212223
channelSize:=3sampleChannel:=make(chanint,channelSize)//Starts up 3 goroutinesforj:=0;j<channelSize;j++{gocountFromStartToEnd("Goroutine1",0,j*2,j,sampleChannel)}//Waits for all goroutines to finish before moving onnumResponse:=0fornumResponse<channelSize{select{caseresponse:=<-sampleChannel:fmt.Println(response)numResponse++//Implement default for non-blocking channel receives/* default: fmt.Println("Nothing received yet.") */}}