From d05638adaceaf4847a1c2dfa541124bec83ec6bb Mon Sep 17 00:00:00 2001 From: legendtkl Date: Tue, 6 Sep 2016 15:45:18 +0800 Subject: [PATCH] concurrency/generator: implement generator pattern --- README.md | 2 +- concurrency/generator.md | 6 ++++++ concurrency/generators.go | 43 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 concurrency/generator.md create mode 100644 concurrency/generators.go diff --git a/README.md b/README.md index 9460ea3..94d98c1 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ A curated collection of idiomatic design & application patterns for Go language. | [Bounded Parallelism](/concurrency/bounded_parallelism.md) | Completes large number of independent tasks with resource limits | ✔ | | [Broadcast](/concurrency/broadcast.md) | Transfers a message to all recipients simultaneously | ✘ | | [Coroutines](/concurrency/coroutine.md) | Subroutines that allow suspending and resuming execution at certain locations | ✘ | -| [Generators](/concurrency/generator.md) | Yields a sequence of values one at a time | ✘ | +| [Generators](/concurrency/generator.md) | Yields a sequence of values one at a time | ✔ | | [Reactor](/concurrency/reactor.md) | Demultiplexes service requests delivered concurrently to a service handler and dispatches them syncronously to the associated request handlers | ✘ | | [Parallelism](/concurrency/parallelism.md) | Completes large number of independent tasks | ✔ | | [Producer Consumer](/concurrency/producer_consumer.md) | Separates tasks from task executions | ✘ | diff --git a/concurrency/generator.md b/concurrency/generator.md new file mode 100644 index 0000000..2161248 --- /dev/null +++ b/concurrency/generator.md @@ -0,0 +1,6 @@ +# Generator Pattern + +[Generator](https://en.wikipedia.org/wiki/Generator_(computer_programming)) is a special routine that can be used to control the iteration behavior of a loop. + +# Implementation and Example +With Go language, we can implement generator in two ways: channel and closure. Fibonacci number generation example can be found in [generators.go](generators.go). \ No newline at end of file diff --git a/concurrency/generators.go b/concurrency/generators.go new file mode 100644 index 0000000..5b2b8b2 --- /dev/null +++ b/concurrency/generators.go @@ -0,0 +1,43 @@ +package main + +import ( + "fmt" +) + +//FibonacciClosure implements fibonacci number generation using closure +func FibonacciClosure() func() int { + a, b := 0, 1 + return func() int { + a, b = b, a+b + return a + } +} + +//FibonacciChan implements fibonacci number generation using channel +func FibonacciChan(n int) chan int { + c := make(chan int) + + go func() { + a, b := 0, 1 + for i := 0; i < n; i++ { + c <- b + a, b = b, a+b + } + close(c) + }() + + return c +} + +func main() { + //closure + nextFib := FibonacciClosure() + for i := 0; i < 20; i++ { + fmt.Println(nextFib()) + } + + //channel + for i := range FibonacciChan(20) { + fmt.Println(i) + } +}