# Channels and Pipelines — Go (Golang)

Source: https://www.skillbyai.com/en/go/c-channels

> Communicate by sending values.

## Unbuffered, buffered, closed

A **channel** passes values between goroutines. An unbuffered channel synchronises sender and receiver; a buffered channel (`make(chan T, n)`) lets sends proceed until the buffer is full. The sender **closes** a channel to signal no more values, and `for v := range ch` stops when it is closed. Directional types (`<-chan T`, `chan<- T`) document who sends and who receives. Chaining stages through channels builds **pipelines**.

## A two-stage pipeline and a buffered channel, run

I ran this with Go 1.27.1 (`go run .` in a module named demo, standard library only). A producer sends 1 to 5, a square stage squares them, and main sums them to 55. The buffered channel holds two values without a receiver, then both are read.

```go
package main

import "fmt"

func producer(n int) <-chan int {
	ch := make(chan int)
	go func() {
		defer close(ch) // closing tells receivers no more values are coming
		for i := 1; i <= n; i++ {
			ch <- i
		}
	}()
	return ch
}

func square(in <-chan int) <-chan int {
	out := make(chan int)
	go func() {
		defer close(out)
		for v := range in {
			out <- v * v
		}
	}()
	return out
}

func main() {
	sum := 0
	for v := range square(producer(5)) { // pipeline: producer -> square -> main
		sum += v
	}
	fmt.Println("sum of squares 1..5 =", sum)

	buf := make(chan string, 2) // buffered: sends do not block until full
	buf <- "a"
	buf <- "b"
	fmt.Println(len(buf), cap(buf), <-buf, <-buf)
}
```

Output:

```
sum of squares 1..5 = 55
2 2 a b
```

## Only the sender closes

Closing from the receiving side, or closing twice, panics; give ownership of closing to the sender.

**Quiz:** What ends a for v := range ch loop?

- [x] The channel being closed and drained
- [ ] Receiving a zero value
- [ ] A timeout by default
- [ ] The buffer becoming full

*Answer:* The channel being closed and drained. Close signals completion.
