diff --git a/README.md b/README.md index dfec8f7..c5abfaa 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ __Concurrency Patterns__: | [Bounded Parallelism](concurrency/bounded_parallelism.md) | Completes large number of independent tasks with resource limits | | TODO: [Broadcast](concurrency/broadcast.md) | Transfers a message to all recipients simultaneously | | TODO: [Coroutines](concurrency/coroutine.md) | Subroutines that allow suspending and resuming execution at certain locations | -| TODO: [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 | | TODO: [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 | | TODO: [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..3871e0a --- /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 iteratoin behavior of a loop. + +# Implementation and Example +With Go language, we can Implemente generator in two ways: channel and closure. Fibnacci 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..504f89f --- /dev/null +++ b/concurrency/generators.go @@ -0,0 +1,44 @@ +package main + +import ( + "fmt" +) + +//implement generator by closure +func FibnacciClosure() func() (ret int) { + a, b := 0, 1 + return func() (ret int) { + ret = b + a, b = b, a+b + return + } +} + +//implement generator by channel +func FibnacciChan(n int) chan int { + ret := make(chan int) + + go func() { + a, b := 0, 1 + for i := 0; i < n; i++ { + ret <- b + a, b = b, a+b + } + close(ret) + }() + + return ret +} + +func main() { + //closure + nextFib := FibnacciClosure() + for i := 0; i < 20; i++ { + fmt.Println(nextFib()) + } + + //channel + for i := range FibnacciChan(20) { + fmt.Println(i) + } +}