Go输出素数——管道,协程,选择器

215 阅读1分钟

这里有一个来自 Go 指导的很赞的例子,打印了输出的素数,使用选择器(‘筛’)作为它的算法。每个 prime 都有一个选择器,如下图:

image.png

代码实例如下:

示例1:

package main

import "fmt"

// Send the sequence 2, 3, 4, ... to channel 'ch'.
func generate(ch chan int) {
   for i := 2; ; i++ {
      ch <- i // Send 'i' to channel 'ch'.
   }
}

// Copy the values from channel 'in' to channel 'out',
// removing those divisible by 'prime'.
func filter(in, out chan int, prime int) {
   for {
      i := <-in // Receive value of new variable 'i' from 'in'.
      if i%prime != 0 {
         out <- i // Send 'i' to channel 'out'.
      }
   }
}

// The prime sieve: Daisy-chain filter processes together.
func main() {
   ch := make(chan int) // Create a new channel.
   go generate(ch)      // Start generate() as a goroutine.
   for {
      prime := <-ch
      fmt.Print(prime, " ")
      ch1 := make(chan int)
      go filter(ch, ch1, prime)
      ch = ch1
   }
}

示例2:

package main
import (
   "fmt"
)
// Send the sequence 2, 3, 4, ... to returned channel
func generate() chan int {
   ch := make(chan int)
   go func() {
      for i := 2; ; i++ {
         ch <- i
      }
   }()
   return ch
}
// Filter out input values divisible by 'prime', send rest to returned channel
func filter(in chan int, prime int) chan int {
   out := make(chan int)
   go func() {
      for {
         if i := <-in; i%prime != 0 {
            out <- i
         }
      }
   }()
   return out
}
func sieve() chan int {
   out := make(chan int)
   go func() {
      ch := generate()
      for {
         prime := <-ch
         ch = filter(ch, prime)
         out <- prime
      }
   }()
   return out
}
func main() {
   primes := sieve()
   for {
      fmt.Println(<-primes)
   }
}