Working with channels requires a different way of programming than when using memory sharing. The idea is to have a set of goroutines, each with its own internal state, exchanging information with other goroutines by passing messages on Go’s channels. In this way, each goroutine’s state is isolated from direct interference by other executions, reducing the risk of race conditions.
Go’s own mantra is not to communicate by shared memory but to instead share memory by communicating. Since memory sharing is more prone to race conditions and requires complex synchronization techniques, we should avoid it when possible and instead use message passing.
In this chapter, we will start by discussing communicating sequential processes (CSP) and then move on to look at the common patterns used when using message passing with channels. We’ll finish this chapter by demonstrating the value of treating channels as first-class objects, meaning that we can pass channels as function arguments and receive them as function return types.