Channels

In computing, a channel is a model for interprocess communication and synchronization via message passing. A message may be sent over a channel, and another process or thread is able to receive messages sent over a channel it has a reference to, as a stream.

Examples in Go
We can use the same looping syntax to iterate over received values in go channels.
package main

import "fmt"

func main() {

    queue := make(chan string, 2)
    queue <- "one"
    queue <- "two"
    close(queue)

    for elem := range queue {
        fmt.Println(elem)
    }
}
Closing a channel indicates that no more values will be sent on it. This can be useful to communicate completion to the channel’s receivers.
package main

import "fmt"

func main() {
    jobs := make(chan int, 5)
    done := make(chan bool)

    // Here's the worker goroutine.
    // It repeatedly receives from jobs with j, more := <-jobs.
    // In this special 2-value form of receive, the more value will be false if jobs has been closed and all values in the channel have already been received.
    // We use this to notify on done when we’ve worked all our jobs.
    go func() {
        for {
            j, more := <-jobs
            if more {
                fmt.Println("received job", j)
            } else {
                fmt.Println("received all jobs")
                done <- true
                return
            }
        }
    }()

    for j := 1; j <= 3; j++ {
        jobs <- j
        fmt.Println("sent job", j)
    }
    close(jobs)
    fmt.Println("sent all jobs")

    <-done
}
When using channels as function parameters, you can specify if a channel is meant to only send or receive values. This specificity increases the type-safety of the program.
package main

import "fmt"

func ping(pings chan<- string, msg string) {
    pings <- msg
}

func pong(pings <-chan string, pongs chan<- string) {
    msg := <-pings
    pongs <- msg
}

func main() {
    pings := make(chan string, 1)
    pongs := make(chan string, 1)
    ping(pings, "passed message")
    pong(pings, pongs)
    fmt.Println(<-pongs)
}
By default Go channels are unbuffered, meaning that they will only accept sends (chan <-) if there is a corresponding receive (<- chan) ready to receive the sent value. Buffered channels accept a limited number of values without a corresponding receiver for those values.
package main

import "fmt"

func main() {

    messages := make(chan string, 2)

    messages <- "buffered"
    messages <- "channel"

    fmt.Println(<-messages)
    fmt.Println(<-messages)
}
Last Run  :
buffered
channel
Channels are the pipes that connect concurrent goroutines. You can send values into channels from one goroutine and receive those values into another goroutine.
package main

import "fmt"

func main() {

    messages := make(chan string)

    // Send a value into a channel using the channel <- syntax.
    go func() { messages <- "ping" }()

    // The <-channel syntax receives a value from the channel.
    msg := <-messages
    fmt.Println(msg)
}