One of Go’s mottos is:
Share memory by communicating, don’t communicate by sharing memory
Here is a mini channel example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main
import "fmt"
func sendMessage(messages chan<- string) {
messages <- "ping"
}
func main() {
messages := make(chan string)
go sendMessage(messages)
msg := <-messages
fmt.Println(msg)
}
What’s happening here is:
- We make a channel,
- We send a message to the channel by calling a function as a goroutine. (If we call a function with go in front, the code will run as a goroutine.)
- We then receive the message from the channel, assign it to a variable, and finally print the message.
- When we run this, we get ping.
By default a channel is unbuffered, meaning it is synchronized. This means that a value must be received from the channel at the same time as it’s being sent. We can verify this by calling sendMessage()
directly instead of as a goroutine. If we do that, the program crashes!
Channels with buffering
It’s also possible to buffer a channel with multiple values. We do this by adding a number to the make call when we create a channel.
1
2
3
4
5
6
7
8
9
10
11
package main
import "fmt"
func main() {
messages := make(chan int, 2)
messages <- 1
messages <- 2
fmt.Println(<-messages)
fmt.Println(<-messages)
}