ruk·si

🐹 Go
Channel Yielding

Updated at 2022-01-15 10:23

Yielding is returning a value from function and giving execution rights to the caller again, but the yielding function will continue where it left it is called again.

Yielding can be made with Go channels.

package main

import "fmt"

func fibonacci(n int) chan int {
    ch := make(chan int)
    go func() {
        a, b := 0, 1
        for i := 0; i < n; i++ {
            a, b = b, a+b
            ch <- a
        }
        close(ch)
    }()
    return ch
}

func main() {
    for x := range fibonacci(10) {
        fmt.Println(x)
    }
}

You can use this pattern to pipe multiple channels together.

package main

import "fmt"

func fibonacci(n int) chan int {
    ch := make(chan int)
    go func() {
        defer close(ch)
        a, b := 0, 1
        for i := 0; i < n; i++ {
            a, b = b, a+b
            ch <- a
        }
    }()
    return ch
}

func prime(n int) bool {
    for i := 2; i < n; i++ {
        if n%i == 0 {
            return false
        }
    }
    return true
}

func filterPrimes(cin chan int) chan int {
    cout := make(chan int)
    go func() {
        defer close(cout)
        for v := range cin {
            if prime(v) {
                cout <- v
            }
        }
    }()
    return cout
}

func main() {
    for p := range filterPrimes(fibonacci(20)) {
        fmt.Println(p)
    }
}

Sources