From d05638adaceaf4847a1c2dfa541124bec83ec6bb Mon Sep 17 00:00:00 2001
From: legendtkl <taokelu@gmail.com>
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)
+	}
+}