Pipeline: обработка в несколько этапов

К задачам
Средняя
Concurrency

Условие задачи

Реализуй простой pipeline: числа от 1 до 10 проходят три стадии: (1) умножение на 2, (2) фильтрация чётных чисел, (3) печать. Каждая стадия — отдельная горутина, связанная каналами.

func generate(out chan<- int) {
    // TODO: отправь числа от 1 до 10
}

func multiply(in <-chan int, out chan<- int) {
    // TODO: умножь на 2
}

func filterEven(in <-chan int, out chan<- int) {
    // TODO: оставь только чётные
}

func main() {
    ch1 := make(chan int)
    ch2 := make(chan int)
    ch3 := make(chan int)

    go generate(ch1)
    go multiply(ch1, ch2)
    go filterEven(ch2, ch3)

    // TODO: печатай всё из ch3
}
func generate(out chan<- int) {
    // TODO: отправь числа от 1 до 10
}

func multiply(in <-chan int, out chan<- int) {
    // TODO: умножь на 2
}

func filterEven(in <-chan int, out chan<- int) {
    // TODO: оставь только чётные
}

func main() {
    ch1 := make(chan int)
    ch2 := make(chan int)
    ch3 := make(chan int)

    go generate(ch1)
    go multiply(ch1, ch2)
    go filterEven(ch2, ch3)

    // TODO: печатай всё из ch3
}

Подсказка

Не забудь закрыть каналы после завершения. Используй defer close(out) внутри горутин.

Решение

Pipeline помогает разделить обработку на независимые этапы. Каждый этап может масштабироваться или заменяться отдельно.

func generate(out chan<- int) {
    defer close(out)
    for i := 1; i <= 10; i++ {
        out <- i
    }
}

func multiply(in <-chan int, out chan<- int) {
    defer close(out)
    for v := range in {
        out <- v * 2
    }
}

func filterEven(in <-chan int, out chan<- int) {
    defer close(out)
    for v := range in {
        if v%2 == 0 {
            out <- v
        }
    }
}

func main() {
    ch1 := make(chan int)
    ch2 := make(chan int)
    ch3 := make(chan int)

    go generate(ch1)
    go multiply(ch1, ch2)
    go filterEven(ch2, ch3)

    for v := range ch3 {
        fmt.Println(v)
    }
}
func generate(out chan<- int) {
    defer close(out)
    for i := 1; i <= 10; i++ {
        out <- i
    }
}

func multiply(in <-chan int, out chan<- int) {
    defer close(out)
    for v := range in {
        out <- v * 2
    }
}

func filterEven(in <-chan int, out chan<- int) {
    defer close(out)
    for v := range in {
        if v%2 == 0 {
            out <- v
        }
    }
}

func main() {
    ch1 := make(chan int)
    ch2 := make(chan int)
    ch3 := make(chan int)

    go generate(ch1)
    go multiply(ch1, ch2)
    go filterEven(ch2, ch3)

    for v := range ch3 {
        fmt.Println(v)
    }
}