Go Channels: The Superhighways of Communication in Go

Go Channels: The Superhighways of Communication in Go

Posted on may 16, 2023  •  13 minutes  • 2733 words.

Welcome to another exciting blog post on learning the Go programming language! Today, we're going to dive into one of the core features of Go: channels. Channels serve as the superhighways of communication in Go, allowing different goroutines to exchange information efficiently and safely. So, fasten your seatbelts, and let's embark on an educational journey through the world of Go channels! What are Channels?

Channels in Go provide a way for goroutines (concurrently executing functions) to communicate and synchronize their actions. Think of channels as pipes that connect goroutines, enabling them to send and receive values, creating a means for coordination and data sharing.

Creating a Channel

To create a channel in Go, we use the built-in make function along with the chan keyword and specify the type of data that will flow through the channel. Here's an example:

This code creates a channel named ch that can transmit integers. You can replace int with any other valid Go type, such as string, float64, or even custom structs. Sending and Receiving Values

Once we have a channel, we can send and receive values using the <- operator. The arrow indicates the direction of the data flow.

Sending a value to a channel:

In this example, we send the value 42 to the channel ch. This operation blocks until there is a goroutine ready to receive the value from the channel.

Receiving a value from a channel:

Here, we receive a value from the channel ch and assign it to the variable value. If there is no value available in the channel, the receiving operation blocks until a sender is ready.

Channel Operations

Channels in Go support several operations that allow us to work with them effectively. Let's explore a few of these operations:

Synchronization: Channels can be used for synchronization purposes, allowing goroutines to coordinate their execution. By using channels, we can make sure that a certain goroutine waits for another goroutine to finish before proceeding.

Blocking: Sending and receiving operations on channels are blocking by default. This means that if a goroutine attempts to send to a channel and there is no receiver, it will wait until a receiver is available, and vice versa. This inherent blocking nature helps prevent race conditions and ensures safe communication.

Buffered Channels: By specifying a buffer size when creating a channel, we can create a buffered channel. Buffered channels can hold a fixed number of values before blocking the send operation. This can be useful when we want to decouple the sending and receiving goroutines temporarily.

Closing Channels: A channel can be closed using the built-in close function. Closing a channel indicates that no more values will be sent on it. Receivers can use a second variable when receiving from a channel to detect if the channel has been closed.

In this example, we create a buffered channel ch with a capacity of 3. We then send three string values on the channel using the send operation ch <- value. Since the channel has a buffer of 3, all three sends will succeed immediately.

We then use the receive operation <-ch to receive the values from the channel. The receives are performed in the same order as the sends, as the buffered channel preserves the order of the values.

Buffered channels are useful when you have a producer that generates values faster than the consumer can process them or when you want to decouple the sending and receiving operations. They allow for a certain level of asynchrony and can help avoid blocking in certain scenarios.

It's important to note that if the buffer is full and a sender attempts to send a value on a buffered channel, it will block until there is available space in the buffer or until a receiver retrieves a value from the channel.

Buffered channels provide a powerful mechanism for managing communication between goroutines with a level of decoupling and asynchrony. They offer a flexible solution in scenarios where you need to balance the workloads of senders and receivers or handle bursts of data without blocking.

Buffered Channels

In Go, channels can be either buffered or unbuffered. Buffered channels have a capacity that defines the number of values that can be held in the channel without a corresponding receiver. Buffered channels provide a way to decouple senders and receivers, allowing them to work at different speeds or independently.

To create a buffered channel, you specify the capacity when using the make function. For example, ch := make(chan int, 5) creates an integer channel with a capacity of 5. This means the channel can hold up to 5 values before blocking the sender. If the channel is full and a sender attempts to send a value, it will block until there is space available in the buffer.

Closing Channels

It's important to properly close channels when they are no longer needed to signal that no more values will be sent on the channel. Closing a channel is achieved using the built-in close function. Here's how it works:

The close function is called with the channel as the argument, indicating that the channel should be closed.

Closing a channel is particularly useful when the receiver needs to detect the end of values being sent. When a channel is closed, the receiver can still receive any remaining values in the channel until it's empty. After that, any subsequent receive operation on the closed channel will yield a zero-value immediately.

To detect if a channel has been closed, Go provides an additional variable when receiving values from a channel. Let's see an example:

In this code snippet, the variable ok is assigned false if the channel has been closed, allowing the receiver to differentiate between a closed channel and an open channel that contains a zero-value.

Closing channels is essential to prevent goroutines from blocking indefinitely on a receive operation. It also allows the garbage collector to reclaim resources associated with the channel.

It's important to note that only the sender should close a channel, as closing a channel that still has pending sends will result in a panic. Therefore, it's good practice to communicate to the receivers when the channel will be closed, so they can safely exit their loops or finish processing the remaining values.

Closing channels appropriately ensures clean and efficient communication between goroutines and helps avoid potential deadlocks or resource leaks.

Error Handling

When receiving a value from a channel, an additional boolean value can be used to check if the channel has been closed. For example:

By checking the value of ok, we can detect if the channel has been closed and take appropriate action.

Channel Direction

In Go, channels can have a direction, specified by using the send-only ( chan<- ) or receive-only ( <-chan ) notation. This feature allows you to enforce and communicate the intended usage of a channel within your codebase. By explicitly declaring the direction of a channel, you provide clarity and safety when it comes to channel operations.

Send-only channels ( chan<- ) indicate that the channel is used only for sending values. Functions or goroutines that receive on a send-only channel will cause a compilation error. This restriction ensures that only designated parts of your codebase can send values on the channel, preventing accidental misuse or data corruption.

Receive-only channels ( <-chan ) indicate that the channel is used only for receiving values. Functions or goroutines that attempt to send on a receive-only channel will result in a compilation error. This limitation guarantees that only specific parts of your codebase can receive values from the channel, reducing the risk of unintended modifications or race conditions.

By enforcing channel direction, you can create clear boundaries and expectations in your code. It provides compile-time safety and prevents runtime errors caused by misusing channels. Channel direction helps with code readability, maintenance, and collaboration, as it communicates the intended purpose of channels to other developers.

You might use channel direction in scenarios where you want to ensure that certain functions or goroutines can only send or receive values through a channel. For example, in a producer-consumer pattern, you can use a send-only channel to allow only the producer goroutines to send data, while the consumer goroutines can only receive data from the channel. This separation of responsibilities provides a clear and structured communication pathway.

Channel direction can also be beneficial in codebases where multiple goroutines interact with the same channels. By explicitly specifying the channel direction, you minimize the chances of accidental misuse or concurrent access issues. This helps in maintaining a well-defined concurrency model and reduces the potential for bugs in your concurrent programs.

Selecting from a Channel

The select statement provides a powerful way to handle multiple channel operations concurrently. It allows you to wait for the first available communication out of several options. With the select statement, you can perform non-blocking communication, implement timeouts, and handle multiple channels simultaneously.

The syntax of the select statement resembles a switch statement, but instead of cases for different values, it has cases for different channel operations. Each case inside the select statement represents a channel operation, which can be a send or receive operation. The select statement chooses the case that is ready for communication, and if multiple cases are ready, it chooses one randomly.

The select statement waits for communication on any of these three cases. Whichever case is ready first will be executed, and the corresponding block of code will be executed. In this example, since the receive from ch2 happens before the receive from ch1, the second case is selected, and "Received from ch2: World" will be printed. If none of the cases are ready within the specified timeout duration, the third case will be executed, and "Timeout: No communication received" will be printed.

The select statement is a powerful construct for handling multiple channels and timeouts in Go. It allows for efficient and flexible coordination of goroutines, enabling concurrent communication scenarios with ease.

Iterating over a channel

You can also iterate over a channel using a for range loop. This allows you to sequentially process the values received from the channel until it is closed. Iterating over a channel is a convenient and concise way to consume values as they become available.

When you iterate over a channel, the loop continues until the channel is closed. The loop receives the values sent on the channel one by one, assigning each value to the iteration variable.

In this example, we have a producer function that sends integer values on a channel ch . The main function creates the channel and starts the producer goroutine. Within the for range loop, we iterate over the channel ch until it is closed, receiving the values sent by the producer and printing them.

The loop continues until the channel is closed. In this case, since the producer function uses the defer statement to close the channel when it finishes sending all the values, the loop will iterate until all the values are received and then terminate gracefully.

By iterating over the channel, you can process the values in the order they are received, ensuring sequential consumption of the channel's contents. This is especially useful when you have a producer-consumer pattern, where one or more goroutines produce values on a channel, and one or more goroutines consume those values.

It's important to note that the range loop will block until a value is available on the channel. If the channel is not closed and no values are being sent, the loop will wait for a value indefinitely. Therefore, it's essential to ensure proper closure of the channel when all values have been sent to avoid deadlock scenarios.

Iterating over a channel provides an elegant and efficient way to consume values as they arrive. It simplifies the code by abstracting away the complexities of managing channel operations explicitly, allowing you to focus on processing the received values sequentially.

What Problems Do Channels Solve?

Channels in Go solve several common problems related to concurrent programming. Let's explore some of the key challenges that channels help address:

Synchronization: Coordinating theexecution of multiple goroutines is a common challenge in concurrent programming. Channels provide a built-in synchronization mechanism, allowing goroutines to exchange information and control their execution flow.

Data Race Conditions: Data races occur when multiple goroutines access and modify shared data concurrently without proper synchronization. Channels help mitigate data race conditions by providing a safe and controlled communication pathway between goroutines.

Resource Sharing: Goroutines often need to share resources or pass data between each other. Channels act as a communication medium, allowing goroutines to share data without the need for explicit locks or other synchronization mechanisms.

When Should You Use Channels?

Channels are particularly useful in the following scenarios:

Communicating Between Goroutines: When you have multiple goroutines that need to exchange information or synchronize their actions, channels provide a simple and efficient means of communication.

Producer-Consumer Patterns: Channels are well-suited for implementing producer-consumer patterns, where one or more goroutines produce data and one or more goroutines consume that data.

Controlling Concurrent Access: When you need to control access to shared resources, channels offer a safe solution. By encapsulating shared resources within goroutines and using channels for exclusive access, you can prevent data races and ensure proper synchronization.

Synchronization and Barrier Patterns: Channels excel in synchronization scenarios, such as waiting for a group of goroutines to complete their tasks before proceeding.

Keep in mind that channels may not be the best solution for every concurrent programming scenario. It's important to consider the specific requirements and characteristics of your program before deciding to use channels.

Go channels are a powerful tool for enabling communication and synchronization between goroutines. By understanding how to create channels, send and receive values, and utilize various channel operations, you can leverage the full potential of concurrent programming in Go.

Channels solve common problems related to synchronization, data races, and resource sharing in concurrent programming. They are particularly useful when you need to communicate between goroutines, implement producer-consumer patterns, control concurrent access to shared resources, or synchronize the execution of multiple goroutines.

With this newfound knowledge, you are well-equipped to harness the power of Go channels and design highly concurrent and reliable applications.

Happy coding with Go channels!

Cartoon headshot of Brad Cypert

Connect with me to follow along on my journey in my career, open source, and mentorship. Occasionally, I'll share good advice and content (quality not guaranteed).

Try adjusting your search query

Advisory boards aren’t only for executives. Join the LogRocket Content Advisory Board today →

LogRocket blog logo

  • Product Management
  • Solve User-Reported Issues
  • Find Issues Faster
  • Optimize Conversion and Adoption
  • Start Monitoring for Free

How to use Go channels

golang tour channels

A Go channel is a communication mechanism that allows Goroutines to exchange data. When developers have numerous Goroutines running at the same time, channels are the most convenient way to communicate with each other.

How To Use Go Channels

Developers often use these channels for notifications and managing concurrency in applications.

In this post, we’ll cover the general uses of Go channels, including how to write into and read from a channel, how to use channels as function parameters, and how to use range to iterate over them.

Creating a Go channel structure

To begin, let’s create a channel in Go using the make function:

Go channels uses

In this section, we’ll review Go channels’ uses and how they can benefit app development.

Using Go channels as futures and promises

Developers often use futures and promises in Go for requests and responses. For example, if we want to implement an async/await pattern, we must add the following:

By simply simulating a long-running process using a 5-second delay, we can send a random integer value to a channel, wait for the value, and receive it.

Using Go channels for notifications

Notifications are one-of-a-kind requests or responses that return values. We usually use a blank struct type as the notification channel element type because the size of the blank struct type is zero, meaning the values of the struct don’t consume memory.

For example, implementing a one-to-one notification with a channel receives a notification value:

This lets us use a value received from a channel to alert another Goroutine waiting to submit a value to the same channel.

Channels can also schedule notifications:

Using Go channels as counting semaphores

To impose a maximum number of concurrent requests, developers frequently use counting semaphores to lock and unlock concurrent processes to control resources and apply mutual exclusions. For example, developers can control the read and write operations in a database.

There are two ways to obtain a piece of a channel semaphore ownership, similar to using channels as mutexes:

  • Acquiring ownership with a send and releasing through a receive
  • Taking possession with a receive and releasing with a send

However, there are some specific rules when owning a channel semaphore. First, each channel allows the exchange of a particular data type, which is also called the element type of the channel.

Second, for a channel to operate properly, someone must receive what is sent via the channel.

For example, we can declare a new channel using the chan keyword, and we can close a channel using the close() function. So, if we block the code using the < - channel syntax to read from the channel, once completed, we can close it.

golang tour channels

Over 200k developers use LogRocket to create better digital experiences

golang tour channels

Finally, when using a channel as a function parameter, we can specify its direction, meaning specifying whether the channel will be used for sending or receiving.

If we know the purpose of a channel in advance, use this capability because it makes programs more robust and safer. This means we can’t send data accidentally to a channel that only receives data, or receive data from a channel that only sends data.

As a result, if we declare that a channel function parameter will be used for reading only and we try to write to it, we get an error message that will most likely save us from nasty bugs.

Writing to a Go channel

The code in this subsection teaches us how to write to a channel in Go. Writing the value x to channel c is as easy as writing c <- x .

The arrow shows the direction of the value; we’ll have no problem with this statement as long as both x and c have the same type.

In the following code, the chan keyword declares that the c function parameter is a channel and must be followed by the type of the channel, which is int . Then, the c <- x statement allows us to write the value x to channel c , and the close() function closes the channel:

Finally, executing the previous code creates the following output:

The strange thing here is that the writeToChannel() function prints the given value only once, which is caused when the second fmt.Println(x) statement never executes.

The reason for this is pretty simple: the c <- x statement blocks the execution of the rest of the writeToChannel() function because nobody is reading what was written to the c channel.

Therefore, when the time.Sleep(1 * time.Second) statement finishes, the program terminates without waiting for writeToChannel() .

More great articles from LogRocket:

  • Don't miss a moment with The Replay , a curated newsletter from LogRocket
  • Learn how LogRocket's Galileo cuts through the noise to proactively resolve issues in your app
  • Use React's useEffect to optimize your application's performance
  • Switch between multiple versions of Node
  • Discover how to use the React children prop with TypeScript
  • Explore creating a custom mouse cursor with CSS
  • Advisory boards aren’t just for executives. Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.

The next section illustrates how to read data from a channel.

Reading from a Go channel

We can read a single value from a channel named c by executing <-c . In this case, the direction is from the channel to the outer scope:

The implementation of the writeToChannel() function is the same as before. In the preceding code, we read from channel c using the <-c notation.

The second time.Sleep(1 * time.Second) statement gives us the time to read from the channel.

The current Go code works fine when the channel is closed; however, if the channel was open, the Go code presented here would have discarded the read value of the channel because we used the _ character in the _, ok := <-c statement.

Use a proper variable name instead of _ if we also want to store the value found in the channel in case it is open.

Executing readCh.go generates the following output:

Although the output is still not deterministic, both the fmt.Println(x) statements of the writeToChannel() function execute because the channel unblocks when we read from it.

Receiving from a closed channel

In this subsection, we’ll review what happens when we try to read from a closed channel using the Go code found in readClose.go .

In this part of the readClose.go program, we must create a new int channel named willClose to write data to it, read the data, and close the channel after receiving the data:

Executing the previous code (saved in readClose.go file) generates the following output:

This means that reading from a closed channel returns the zero value of its data type, which in this case is 0 .

Channels as function parameters

While we did not use function parameters when working with readCh.go or writeCh.go , Go does allow us to specify the direction of a channel when using it as a function parameter, meaning whether it’s used for reading or writing.

These two types of channels are called unidirectional channels, whereas channels are bidirectional by default.

Examine the Go code of the following two functions:

Although both functions implement the same functionality, their definitions are slightly different. The difference is created by the <- symbol found on the right of the chan keyword in the definition of the f2() function.

This denotes that the c channel can only write. If the code of a Go function attempts to read from a write-only channel (also known as a send-only channel) parameter, the Go compiler generates the following error message:

Similarly, we can have the following function definitions:

The definition of f2() combines a read-only channel named in with a write-only channel named out. If we accidentally try to write and close a read-only channel (also known as a receive-only channel) parameter of a function, we get the following error message:

Range over Go channels

We can use range syntax in Golang to iterate over a channel to read its values. Iterating here applies the first-in, first-out (FIFO) concept: as long as we add data to the channel buffer, we can read from the buffer like a queue:

As mentioned above, using range to iterate from a channel applies the FIFO principle (reading from a queue). So, executing the previous code outputs the following:

Go channels are used for communicating between concurrently running functions by sending and receiving a specific element type’s data. When we have numerous Goroutines running at the same time, channels are the most convenient way for them to communicate with one another.

Thanks for reading and happy coding! 🙂

Get set up with LogRocket's modern error tracking in minutes:

  • Visit https://logrocket.com/signup/ to get an app ID

Install LogRocket via npm or script tag. LogRocket.init() must be called client-side, not server-side

Share this:

  • Click to share on Twitter (Opens in new window)
  • Click to share on Reddit (Opens in new window)
  • Click to share on LinkedIn (Opens in new window)
  • Click to share on Facebook (Opens in new window)

golang tour channels

Stop guessing about your digital experience with LogRocket

Recent posts:.

Comparing Mutative Vs Immer Vs Reducers For Data Handling In React

Comparing React state tools: Mutative vs. Immer vs. reducers

Mutative processes data with better performance than both Immer and native reducers. Let’s compare these data handling options in React.

golang tour channels

Radix UI adoption guide: Overview, examples, and alternatives

Radix UI is quickly rising in popularity and has become an excellent go-to solution for building modern design systems and websites.

golang tour channels

Understanding the CSS revert-layer keyword

In this article, we’ll explore CSS cascade layers — and, specifically, the revert-layer keyword — to help you refine your styling strategy.

golang tour channels

Exploring Nushell, a Rust-powered, cross-platform shell

Nushell is a modern, performant, extensible shell built with Rust. Explore its pros, cons, and how to install and get started with it.

golang tour channels

Leave a Reply Cancel reply

Welcome to tutorial no. 22 in Golang tutorial series .

In the previous tutorial , we discussed about how concurrency is achieved in Go using Goroutines. In this tutorial we will discuss about channels and how Goroutines communicate using channels.

What are channels

Channels can be thought of as pipes using which Goroutines communicate. Similar to how water flows from one end to another in a pipe, data can be sent from one end and received from the other end using channels.

Declaring channels

Each channel has a type associated with it. This type is the type of data that the channel is allowed to transport. No other type is allowed to be transported using the channel.

chan T is a channel of type T

The zero value of a channel is nil . nil channels are not of any use and hence the channel has to be defined using make similar to maps and slices .

Let’s write some code that declares a channel.

Run program in playground

The channel a declared in line no. 6 is nil as the zero value of a channel is nil . Hence the statements inside the if condition are executed and the channel is defined. a in the above program is a int channel. This program will output,

As usual, the short hand declaration is also a valid and concise way to define a channel.

The above line of code also defines an int channel a .

Sending and receiving from a channel

The syntax to send and receive data from a channel is given below,

The direction of the arrow with respect to the channel specifies whether the data is sent or received.

In the first line, the arrow points outwards from a and hence we are reading from channel a and storing the value to the variable data .

In the second line, the arrow points towards a and hence we are writing to channel a .

Sends and receives are blocking by default

Sends and receives to a channel are blocking by default. What does this mean? When data is sent to a channel, the control is blocked in the send statement until some other Goroutine reads from that channel. Similarly, when data is read from a channel, the read is blocked until some Goroutine writes data to that channel.

This property of channels is what helps Goroutines communicate effectively without the use of explicit locks or conditional variables that are quite common in other programming languages.

It’s ok if this doesn’t make sense now. The upcoming sections will add more clarity on how channels are blocking by default.

Channel example program

Enough of theory :). Let’s write a program to understand how Goroutines communicate using channels.

We will actually rewrite the program we wrote when learning about Goroutines using channels here.

Let me quote the program here from the last tutorial.

This was the program from the last tutorial. We use a sleep here to make the main Goroutine wait for the hello Goroutine to finish. If this doesn’t make sense to you, I recommend reading the tutorial on Goroutines

We will rewrite the above program using channels.

In the above program, we create a done bool channel in line no. 12 and pass it as a parameter to the hello Goroutine. In line no. 14 we are receiving data from the done channel. This line of code is blocking which means that until some Goroutine writes data to the done channel, the control will not move to the next line of code. Hence this eliminates the need for the time.Sleep which was present in the original program to prevent the main Goroutine from exiting.

The line of code <-done receives data from the done channel but does not use or store that data in any variable. This is perfectly legal.

Now we have our main Goroutine blocked waiting for data on the done channel. The hello Goroutine receives this channel as a parameter, prints Hello world goroutine and then writes to the done channel. When this write is complete, the main Goroutine receives the data from the done channel, it is unblocked and then the text main function is printed.

This program outputs

Let’s modify this program by introducing a sleep in the hello Goroutine to better understanding this blocking concept.

Run in playground

In the above program, we have introduced a sleep of 4 seconds to the hello function in line no. 10.

This program will first print Main going to call hello go goroutine . Then the hello Goroutine will be started and it will print hello go routine is going to sleep . After this is printed, the hello Goroutine will sleep for 4 seconds and during this time main Goroutine will be blocked since it is waiting for data from the done channel in line no. 18 <-done . After 4 seconds hello go routine awake and going to write to done will be printed followed by Main received data .

Another example for channels

Let’s write one more program to understand channels better. This program will print the sum of the squares and cubes of the individual digits of a number.

For example, if 123 is the input, then this program will calculate the output as

squares = (1 * 1) + (2 * 2) + (3 * 3) cubes = (1 * 1 * 1) + (2 * 2 * 2) + (3 * 3 * 3) output = squares + cubes = 50

We will structure the program such that the squares are calculated in a separate Goroutine, cubes in another Goroutine and the final summation happens in the main Goroutine.

The calcSquares function in line no. 7 calculates the sum of the squares of the individual digits of the number and sends it to the squareop channel. Similarly the calcCubes function in line no. 17 calculates the sum of cubes of the individual digits of the number and sends it to the cubeop channel.

These two functions are run as separate Goroutines in line no. 31 and 32 and each is passed a channel to write to as the parameter. The main Goroutine waits for data from both these channels in line no. 33. Once the data is received from both the channels, they are stored in squares and cubes variables and the final output is computed and printed. This program will print

One important factor to consider while using channels is deadlock. If a Goroutine is sending data on a channel, then it is expected that some other Goroutine should be receiving the data. If this does not happen, then the program will panic at runtime with Deadlock .

Similarly, if a Goroutine is waiting to receive data from a channel, then some other Goroutine is expected to write data on that channel, else the program will panic.

In the program above, a channel ch is created and we send 5 to the channel in line no. 6 ch <- 5 . In this program no other Goroutine is receiving data from the channel ch . Hence this program will panic with the following runtime error.

Unidirectional channels

All the channels we discussed so far are bidirectional channels, that is data can be both sent and received on them. It is also possible to create unidirectional channels, that is channels that only send or receive data.

In the above program, we create send only channel sendch in line no. 10. chan<- int denotes a send only channel as the arrow is pointing to chan . We try to receive data from a send only channel in line no. 12. This is not allowed and when the program is run, the compiler will complain stating,

./prog.go:12:14: invalid operation: <-sendch (receive from send-only type chan<- int)

All is well but what is the point of writing to a send only channel if it cannot be read from!

This is where channel conversion comes into use. It is possible to convert a bidirectional channel to a send only or receive only channel but not the vice versa.

In line no. 10 of the program above, a bidirectional channel chnl is created. It is passed as a parameter to the sendData Goroutine in line no. 11. The sendData function converts this channel to a send only channel in line no. 5 in the parameter sendch chan<- int . So now the channel is send only inside the sendData Goroutine but it’s bidirectional in the main Goroutine. This program will print 10 as the output.

Closing channels and for range loops on channels

Senders have the ability to close the channel to notify receivers that no more data will be sent on the channel.

Receivers can use an additional variable while receiving data from the channel to check whether the channel has been closed.

In the above statement ok is true if the value was received by a successful send operation to a channel. If ok is false it means that we are reading from a closed channel. The value read from a closed channel will be the zero value of the channel’s type. For example, if the channel is an int channel, then the value received from a closed channel will be 0 .

In the program above, the producer Goroutine writes 0 to 9 to the chnl channel and then closes the channel. The main function has an infinite for loop in line no.16 which checks whether the channel is closed using the variable ok in line no. 18. If ok is false it means that the channel is closed and hence the loop is broken. Else the received value and the value of ok is printed. This program prints,

The for range form of the for loop can be used to receive values from a channel until it is closed.

Let’s rewrite the program above using a for range loop.

The for range loop in line no. 16 receives data from the ch channel until it is closed. Once ch is closed, the loop automatically exits. This program outputs,

The program from Another example for channels section can be rewritten with more code reusability using for range loop.

If you take a closer look at the program you can notice that the code which finds the individual digits of a number is repeated in both calcSquares function and calcCubes function. We will move that code to its own function and call it concurrently.

The digits function in the program above now contains the logic for getting the individual digits from a number and it is called by both calcSquares and calcCubes functions concurrently. Once there are no more digits in the number, the channel is closed in line no. 13. The calcSquares and calcCubes Goroutines listen on their respective channels using a for range loop until it is closed. The rest of the program is the same. This program will also print

This brings us to the end of this tutorial. There are few more concepts in channels such as buffered channels , worker pools and select . We will discuss them in separate tutorials of their own. Thanks for reading.

I hope you liked this tutorial. Please leave your feedback and comments. Please consider sharing this tutorial on twitter and LinkedIn . Have a good day.

If you would like to advertise on this website, hire me, or if you have any other software development needs please email me at naveen[at]golangbot[dot]com .

Next tutorial - Buffered Channels and Worker Pools

golang tour channels

Channels in Golang

Channels are a medium that the goroutines use in order to communicate effectively. It is the most important concept to grasp after understanding how goroutines work. This post aims to provide a detailed explanation of the working of the channels and their use cases in Go.

Golang Channels syntax

In order to use channels, we must first create it. We have a very handy function called make which can be used to create channels. A channel is dependent on the data type it carries. That means we cannot send strings via int channels. So, we need to create a channel-specific to its purpose.

Here’s how we create channels. The chan is a keyword which is used to declare the channel using the make function.

To send and receive data using the channel we will use the channel operator which is <- .

Zero-value of a channel

A channel that is not initialized or zero-value is nil.

Working with channels

Now, we will try sending and receiving data using channels. Let’s start by creating a basic goroutine that will send data via a channel which we will be receiving from the main goroutine.

Here, in this example, we send data via a goroutine and receive data accordingly. Now, we will try sending custom data such as a struct.

Sending custom data via channels

Custom data can be sent just like any other data type. When creating and using the channels we need to be aware of using the correct data type when creating the channel. Here is an example that sends a Person struct via a channel.

The send and receive operation

Tha channels operations are by default blocking. That means when we use any of the send or receive operation the channels blocks unless the work is done. Thus allowing them to be synchronized.

Using directional channels

Channels can be unidirectional. That means channels can be declared such that the channel can only send or receive data. This is an important property of channels.

In the code above, we use a channel which is a send-only channel. That means data can only be sent into it but when we try receiving any data from the channel it produces errors.

The syntax is as follows:

Closing a channel

A channel can be closed after the values are sent through it. The close function does that and produces a boolean output which can then be used to check whether it is closed or not.

Using a loop with a channel

A range loop can be used to iterate over all the values sent through the channel. Here is an example showing just that.

This program produces an output shown below:

Go Channel Range Loop

As we can see, that the loop is done over all the values the channel sends. The program outputs as expected. The channel also should be closed after sending the values.

Instantly share code, notes, and snippets.

@tetsuok

tetsuok / answer_word_count.go

  • Download ZIP
  • Star 11 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Embed Embed this gist in your website.
  • Share Copy sharable link for this gist.
  • Clone via HTTPS Clone using the web URL.
  • Learn more about clone URLs
  • Save tetsuok/2280069 to your computer and use it in GitHub Desktop.

@Tusharsb

Tusharsb commented Aug 23, 2018

Sorry, something went wrong.

@lealLuo

lealLuo commented Dec 2, 2018

I think mine is stupid but it works ...

@jhenriquez

jhenriquez commented Feb 11, 2019 • edited

@banothurameshnaik

banothurameshnaik commented Sep 20, 2019

@everbslab

everbslab commented Oct 12, 2019

@olehcambel

olehcambel commented Apr 17, 2020

@kaen98

kaen98 commented Apr 20, 2020 • edited

@Andrew-He

Andrew-He commented Apr 21, 2020

@denddyprod

denddyprod commented May 17, 2020 • edited

I had some problems with testing function wc.test so I tested it manually

@atyrian

atyrian commented Jun 14, 2020

package main

import ( "golang.org/x/tour/wc" "strings" )

func WordCount(s string) map[string]int { words := strings.Fields(s) m := make(map[string]int, len(words)) for _,v := range words{ m[v] += 1 } return m }

func main() { wc.Test(WordCount) }

@geekyarthurs

geekyarthurs commented Jun 22, 2020

@coderhh

coderhh commented Jun 25, 2020 • edited

Here is my answer:.

@Raghav2211

Raghav2211 commented Sep 7, 2020 • edited

@albertleng

albertleng commented Jan 9, 2021

@hefedev

hefedev commented Mar 5, 2021

@ichiro-ss

ichiro-ss commented Mar 12, 2021

Without "strings".

I'm a beginner so please give me some advice

@ramesh-km

ramesh-km commented Mar 28, 2021

@xfelmutx

xfelmutx commented Apr 2, 2021 • edited

@coderinblack08

coderinblack08 commented Apr 6, 2021

@DrCoffee84

DrCoffee84 commented May 14, 2021

without Split or Fields func

@DonkovtsevArthur

DonkovtsevArthur commented Nov 19, 2021 • edited

@laura-brizuela

laura-brizuela commented Nov 19, 2021 via email

@Devdha

Devdha commented Dec 14, 2021 • edited

@Rexoen

Rexoen commented Aug 7, 2022 • edited

@krapie

krapie commented Dec 7, 2022

@alkstsgv

alkstsgv commented Jun 19, 2023

@0riginaln0

0riginaln0 commented Aug 20, 2023

@sno-windy

sno-windy commented Oct 30, 2023

Here is my struggling answer without strings.Fields.

@poirierunited

poirierunited commented Nov 10, 2023

func WordCount(s string) map[string]int { counterMap := make(map[string]int)

@j4breu

j4breu commented Mar 13, 2024 • edited

NBC Olympics Paris 2024 logo

  • OlympicTalk ,

Valero Texas Open - Round Two

  • Brentley Romine ,

MLB: Toronto Blue Jays at Tampa Bay Rays

Trending Teams

Pga tour lays out how the player equity program will work.

  • Rex Hoggard ,
  • Rex Hoggard

In February, PGA Tour commissioner Jay Monahan introduced the rough outline of the Player Equity Program, a vesting plan for the circuit’s new for-profit arm that will carve up a hefty portion of the initial $1.5 billion investment from Strategic Sports Group. On Wednesday, players were given a more detailed version of the program, PGA Tour chief competitions officer Tyler Dennis confirmed on “Golf Central.”

The initial player equity grants will be approximately $930 million distributed to 193 players via four categories, starting with the game’s stars. Monahan informed players on Wednesday via a letter of their individual grants.

“There’s no other sports league in the world that has this significant number of their athletes as owners of their own sports organization,” Dennis said.

“We want to grow the PGA Tour in many different ways and having the alignment of players as player-owners with the organization is going to allow us to drive that quickly forward.”

The first group includes 36 players receiving $750 million in equity based on the last five years of play. “Career Points” will be awarded based on how many years a player has been a Tour member, how many times they earned a spot in the Tour Championship and how many times they have won, with extra points awarded for high-profile victories like the majors, The Players Championship and the FedExCup.

Group 2’s share of the initial equity will be much smaller ($75 million) and will be granted to 64 players. The group is considered “steady performers and up-and-comers” and will be based on FedExCup points earned over the last three years.

Equity to Group 3 will be $30 million going to 57 players based on career earnings and how many times a player finished inside the top 125 in FedExCup points.

The final group will include “past legends,” like Jack Nicklaus and Tom Watson, with $75 million going to 36 players based on the “Career Points” formula. Those grants will only be awarded to “past legends” that are living.

Perhaps most important to players will be the program’s eight-year vesting period. The grants will be worth 50% of their value after four years, 75% after six and 100% after eight years, when a player will be able to sell their equity in PGA Tour Enterprises, the for-profit arm the Tour created for the program. At each vesting benchmark players will be responsible to pay taxes on the grants.

The program has been created to encourage loyalty to the Tour in the face of ongoing challenges from LIV Golf, and the requirements of maintaining membership (which includes a minimum of 15 starts each year) would mean players who join LIV Golf would not be eligible for the program or would give up any unvested equity if they were to join the rival circuit.

“We want the players to be fully aligned with their organization,” Dennis said. “It’s something no other sport has done before and we’re seeing an incredible amount of excitement about that.”

SSG valued the PGA Tour at $12.3 billion when the group, which is led by Fenway Sports, became a minority investor and the assumption is that valuation will continue to increase like most professional sports franchises in the United States.

The remainder of the initial $1.5 billion investment (roughly $600 million) will be awarded in recurring player grants of $100 million each year, beginning in 2025 through 2030. These grants will be awarded based on performance and Player Impact Program results with an eye toward young talent, like Ludvig Åberg or Nick Dunlap.

  • CBSSports.com
  • Fanatics Sportsbook
  • CBS Sports Home
  • Champions League
  • Motor Sports
  • High School
  • Horse Racing 

mens-brackets-180x100.jpg

Men's Brackets

womens-brackets-180x100.jpg

Women's Brackets

Fantasy Baseball

Fantasy football, football pick'em, college pick'em, fantasy basketball, fantasy hockey, franchise games, 24/7 sports news network.

cbs-sports-hq-watch-dropdown.jpg

  • CBS Sports Golazo Network
  • PGA Tour on CBS
  • UEFA Champions League
  • UEFA Europa League
  • Italian Serie A
  • Watch CBS Sports Network
  • TV Shows & Listings

The Early Edge

201120-early-edge-logo-square.jpg

A Daily SportsLine Betting Podcast

With the First Pick

wtfp-logo-01.png

NFL Draft is coming up!

  • Podcasts Home
  • The First Cut Golf
  • Beyond the Arc
  • Eye On College Basketball
  • NFL Pick Six
  • Cover 3 College Football
  • Fantasy Football Today
  • My Teams Organize / See All Teams Help Account Settings Log Out

2024 Zurich Classic live stream, TV schedule, where to watch online, channel, tee times, radio, golf coverage

Grab a partner as this team-style event on the pga tour wraps up sunday.

zurich-classic-general-getty.jpg

For the seventh straight year, golfers are in the Bayou taking part in the PGA Tour's annual team-style event. The 2024 Zurich Classic welcomed 80 teams of two as partners hoping to grab a trophy by week's end at TPC Louisiana.

Headlining the action are the two players who seemingly do everything together: Xander Schauffele and Patrick Cantlay. The good friends were victorious in their first go around in 2022 but failed to defend their title a season ago. They started well this go-around but will need to make some major gains on Sunday if they hope to win two of three titles in New Orleans.

A new pairing making its debut features world No. 2 Rory McIlroy -- in his first tournament appearance -- playing alongside Shane Lowry. The two have shared Ryder Cup moments together are near the top of the Zurich Classic leaderboard , sitting just two strokes back entering the final 18 holes Sunday.

Will Zalatoris and Sahith Theegala also entered as a strong duo on paper, as was the case with Collin Morikawa and Kurt Kitayama. Adam Hadwin and Nick Taylor hoped to do one better than their runner-up performance in 2023 with Corey Conners and Taylor Pendrith also starring as an all-Canadian team. Brothers Alex and Matt Fitzpatrick team up for the second straight year with Rasmus and Nicolai Hojgaard, plus Parker and Pierceson Coody, also making this week a family affair.

All times Eastern; streaming start times approximated

Round 4 - Sunday

Round starts:  10:30 a.m.

PGA Tour Live:  10:30 a.m. -  6 p.m. --  PGA Tour Live

Early TV coverage:  12:45 - 2:45 p.m. on Golf Channel,  fubo  (Try for free) Live streaming:  12:45 - 2:45 p.m. on Peacock

Live TV coverage:  3-6 p.m. on CBS Live simulcast:  3-6 p.m. on  CBSSports.com  and the  CBS Sports App

Radio:  1-6 p.m. --  PGA Tour Radio  

Our Latest Golf Stories

koepka-file-friday.jpg

2024 PGA Championship odds, picks, best bets, field

Cbs sports staff • 5 min read.

rory-mcilroy-shane-lowry-round-1-2024-zurich-classic-g.jpg

McIlroy, Lowry hang on to co-lead at Zurich Classic

Kyle porter • 3 min read, rory mcilroy, shane lowry leading after day 1 at zurich, patrick mcdonald • 5 min read.

frankie-capan-iii-korn-fery-tour-g.jpg

Frankie Capan III shoots 58 on Korn Ferry Tour

Patrick mcdonald • 1 min read, 2024 zurich classic odds, picks, computer simulation.

RBC Heritage - Final Round

McIlroy set to return to PGA Tour board

Kyle porter • 4 min read, share video.

golang tour channels

How to watch 2024 Zurich Classic

golang tour channels

Scheffler on a run not seen since Woods

golang tour channels

Report: Woods, McIlroy set to receive loyalty bonuses

golang tour channels

Rory McIlroy on expected return to PGA Tour board

golang tour channels

2024 PGA Championship odds: Scheffler on top

golang tour channels

Nelly Korda ties record with fifth straight LPGA win

golang tour channels

Scheffler stays hot with fourth win in last five starts

golang tour channels

Scheffler earnings up to $16.3 million since March

golang tour channels

Davis Love III enthused about golf's young stars

golang tour channels

Johnny Damon: How I started loving golf

IMAGES

  1. Channels In Golang

    golang tour channels

  2. Channels in Golang

    golang tour channels

  3. Golang Channel

    golang tour channels

  4. Golang : introduction to channels

    golang tour channels

  5. Channel in Golang

    golang tour channels

  6. Golang Channel

    golang tour channels

VIDEO

  1. INSTALLATION & EINRICHTUNG 🔹 Go / Golang Introduction 🔹 German Tutorial

  2. Analyzing 3 Home Tour Channels

  3. Golang Channels in 16 Minutes!

  4. Go WebSocket in 4 minutes! (Detailed Explanation)

  5. A Real World Project Use Case Of Golang's Sync.WaitGroup

  6. Channels

COMMENTS

  1. A Tour of Go

    This allows goroutines to synchronize without explicit locks or condition variables. The example code sums the numbers in a slice, distributing the work between two goroutines. Once both goroutines have completed their computation, it calculates the final result. < 2/11 >. channels.go Syntax Imports. 23. 1.

  2. A Tour of Go

    Welcome to a tour of the Go programming language . The tour is divided into a list of modules that you can access by clicking on A Tour of Go on the top left of the page. You can also view the table of contents at any time by clicking on the menu on the top right of the page. Throughout the tour you will find a series of slides and exercises ...

  3. Go Channels: The Superhighways of Communication in Go

    Learn about Go channels, the powerful communication mechanism in Go programming. Discover how channels enable safe and efficient coordination between goroutines, solve synchronization challenges, and mitigate data race conditions. Explore channel creation, sending and receiving values, and essential channel operations. Find out when to use channels and how they address common concurrent ...

  4. Ultimate Go Tour

    Ultimate Go Tour. Patch 35. This is material for any intermediate-level developer who has some experience with other programming languages and wants to learn Go. We believe this material is perfect for anyone who wants a jump start in learning Go or who wants a more thorough understanding of the language and its internals.

  5. How to use Go channels

    Learn how these channels are the most convenient way to communicate in Go. ... We can use range syntax in Golang to iterate over a channel to read its values. Iterating here applies the first-in, first-out (FIFO) concept: as long as we add data to the channel buffer, we can read from the buffer like a queue: ...

  6. Mastering Go Channels

    Aug 15, 2023. 2. Go, often referred to as Golang, is a statically typed, compiled programming language that has become increasingly popular due to its simplicity, concurrency support, and ...

  7. Diving into Golang channels

    Channels are a typed conduit through which you can send and receive values with the channel operator, <-. golang tour. Pretty clear definition right? An even clearer analogy is they are the little green multi-dimensional phone lines that connect different goroutines (dimensions) in your golang app. green threads! Creating a channel.

  8. Exploring the Depths of Golang Channels: A Comprehensive Guide

    G2 Receiving Data from the Channel. Acquire the lock on the channel. Dequeue task₀ from the buffer, make a copy and assign it to variable t. Release the lock, allowing G2 to proceed.

  9. Go (Golang) Channels Tutorial with Examples

    The direction of the arrow with respect to the channel specifies whether the data is sent or received. In the first line, the arrow points outwards from a and hence we are reading from channel a and storing the value to the variable data.. In the second line, the arrow points towards a and hence we are writing to channel a.. Sends and receives are blocking by default

  10. A Tour of Go

    Basics. The starting point, learn all the basics of the language. Declaring variables, calling functions, and all the things you need to know before moving to the next lessons. Packages, variables, and functions. Learn the basic components of any Go program. Learn how to control the flow of your code with conditionals, loops, switches and defers.

  11. Building Golang Channels From Scratch

    Close will actually close the channel so no more data can be sent to it. However, you can still read any data that is still in the channel. Next is used to iterate over the data in the channel ...

  12. The Go Programming Language

    Welcome to the Go channel, where we hope to make you love programming again! Go is an open-source programming language supported by Google. Join our communit...

  13. Channels in Golang

    Golang Channels syntax. In order to use channels, we must first create it. We have a very handy function called make which can be used to create channels. A channel is dependent on the data type it carries. That means we cannot send strings via int channels. So, we need to create a channel-specific to its purpose.

  14. Go Channel: Master the Art of Concurrency in Golang

    A channel in Go is a communication pathway between goroutines. It allows them to exchange values and synchronize their actions. Channels are simple to create and use, enabling safe and efficient data transmission. They can have directionality, restricting sending or receiving operations.

  15. A Tour of Go

    The Go Playground. This tour is built atop the Go Playground, a web service that runs on golang.org 's servers. The service receives a Go program, compiles, links, and runs the program inside a sandbox, then returns the output. There are limitations to the programs that can be run in the playground:

  16. Anatomy of Channels in Go

    var data int. data = <- c. Now data coming from the channel c which is of type int can be stored into the variable data of type int. Above syntax can be re-written using shorthand syntax as below ...

  17. Channels in 'A Tour of Go' : r/golang

    Go to golang r/golang • by 632isMyName. View community ranking In the Top 1% of largest communities on Reddit. Channels in 'A Tour of Go' Hey, so I'm a computer science student looking for a general purpose language that's straight forward to write, not a giant heap of different concepts, but also not obstructively simple like python. ...

  18. concurrency

    I'm looking at this mit solution to this A Tour of Go exercise // // Concurrent crawler with channels // func worker(url string, ch chan []string, fetcher Fetcher) { urls, err := fetcher.Fetch... Stack Overflow. About; ... Simple solution for golang tour webcrawler exercise. 2 Go web crawler gets stuck. 1 Go Tour #10: Lost in concurrency ...

  19. An answer of the exercise: Maps on a tour of Go · GitHub

    An answer of the exercise: Maps on a tour of Go. GitHub Gist: instantly share code, notes, and snippets.

  20. PGA Tour lays out how the Player Equity Program will work

    Perhaps most important to players will be the program's eight-year vesting period. The grants will be worth 50% of their value after four years, 75% after six and 100% after eight years, when a player will be able to sell their equity in PGA Tour Enterprises, the for-profit arm the Tour created for the program.

  21. Mastering Communication with Channels in GoLang for Concurrent ...

    4.Close Channels Properly: When you're done sending data through a channel, it's good practice to close the channel using close(ch). This indicates to the receivers that no more data will be sent.

  22. A Tour of Go

    This tour is also available as a stand-alone program that you can use without access to the internet. It builds and runs the code samples on your own machine. To run the tour locally, you'll need to first install Go and then run:

  23. 2024 Zurich Classic live stream, TV schedule, where to watch online

    2024 Zurich Classic live stream, TV schedule, where to watch online, channel, tee times, radio, golf coverage Grab a partner as this team-style event on the PGA Tour wraps up Sunday

  24. A Tour of Go

    A sender can close a channel to indicate that no more values will be sent. Receivers can test whether a channel has been closed by assigning a second parameter to the receive expression: after. v, ok := <-ch. ok is false if there are no more values to receive and the channel is closed. The loop for i := range c receives values from the channel ...