generator

package
v1.2.117 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 13, 2024 License: MIT Imports: 1 Imported by: 0

README

GoDoc Report card

Generator

Generator behaves like Generator in python or ES6, with yield and next statements.

Generator function contains one or more yield statement.
Generator functions allow you to declare a function that behaves like an iterator, i.e. it can be used in a for loop.
Generator generators are a simple way of creating iterators. All the overhead we mentioned above are automatically handled by generators.
Simply speaking, a generator is a function that returns an object (iterator) which we can iterate over (one value at a time).
If desired, go to python or ES6 for more information.

Example

Golang Generators
package main

import (
    "fmt"

    "github.com/searKing/golang/go/go/generator"
)

func main() {
    g := func(i int) *generator.Generator {
        return generator.GeneratorFunc(func(yield generator.Yield) {
            yield(i)
            yield(i + 10)
        })
    }

    gen := g(10)
    
    // WAY 1, by channel
    for msg := range gen.C {
        fmt.Println(msg)
    }
    // WAY 2, by Next
    //for {
    //	msg, ok := gen.Next()
    //	if !ok {
    //	    return
    //	}
    //	fmt.Println(msg)
    //}

    // Output:
    // 10
    // 20
}
Python Generators
# A simple generator function
def generator(i):
    n = 1
    # Generator function contains yield statements
    yield i
    yield i+10

# Using for loop
for item in generator(10):
    print(item) 

# Output:
# 10
# 20
JavaScript Generators
function* generator(i) {
  yield i;
  yield i + 10;
}

const gen = generator(10);

console.log(gen.next().value);
// expected output: 10

console.log(gen.next().value);
// expected output: 20

Download/Install

The easiest way to install is to run go get -u github.com/searKing/golang/go/go/generator.
You can also manually git clone the repository to $GOPATH/src/github.com/searKing/golang/go/go/generator.

Inspiring Generators

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func GeneratorVariadicFunc deprecated

func GeneratorVariadicFunc(f func(yield Yield, args ...any)) func(args ...any) *Generator

Deprecated: Use GeneratorFunc wrapped by closure instead.

Example
package main

import (
	"fmt"

	"github.com/searKing/golang/go/go/generator"
)

func main() {
	g := func(i int) *generator.Generator {
		g := generator.GeneratorVariadicFunc(func(yield generator.Yield, args ...any) {
			i := (args[0]).(int)
			if !yield(i) {
				return
			}
			if !yield(i + 10) {
				return
			}
		})

		gen := g(i)
		return gen
	}

	gen := g(10)

	for msg := range gen.C {
		fmt.Println(msg)
	}

}
Output:

10
20

Types

type Generator

type Generator struct {
	// Used by Next, to notify or deliver what is generated, as next in python or ES6
	C <-chan any
	// contains filtered or unexported fields
}

Generator behaves like Generator in python or ES6 Generator function contains one or more yield statement. Generator functions allow you to declare a function that behaves like an iterator, i.e. it can be used in a for loop. see https://wiki.python.org/moin/Generators see https://www.programiz.com/python-programming/generator see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*

func GeneratorFunc

func GeneratorFunc(f func(yield Yield)) *Generator

GeneratorFunc returns an object (iterator) which we can iterate over (one value at a time). It returns a Generator that can be used to cancel the call using its Stop method. Iterate will be stopped when f is return or Stop is called.

Example
package main

import (
	"fmt"

	"github.com/searKing/golang/go/go/generator"
)

func main() {
	g := func(i int) *generator.Generator {
		return generator.GeneratorFunc(func(yield generator.Yield) {
			if !yield(i) {
				return
			}
			if !yield(i + 10) {
				return
			}
		})
	}

	gen := g(10)

	for msg := range gen.C {
		fmt.Println(msg)
	}

}
Output:

10
20

func GeneratorFuncWithSupplier

func GeneratorFuncWithSupplier(supplierC <-chan any, f func(msg any)) *Generator

GeneratorFuncWithSupplier waits for the supplierC to supply and then calls f in its own goroutine every time. It returns a Generator that can be used to cancel the call using its Stop method. Consume will be stopped when supplierC is closed.

func GeneratorWithSupplier

func GeneratorWithSupplier(supplierC <-chan any) *Generator

GeneratorWithSupplier is like GeneratorFunc. But it's data src is from supplierC. Iterate will be stopped when supplierC is closed or Stop is called.

Example
package main

import (
	"fmt"

	"github.com/searKing/golang/go/go/generator"
)

func main() {
	var g *generator.Generator

	supplierC := make(chan any)
	supplierF := func(i int) {
		consumer := g.Yield(supplierC)
		if !consumer(i) {
			return
		}
		if !consumer(i + 10) {
			return
		}
		close(supplierC)
	}
	g = generator.GeneratorWithSupplier(supplierC)
	go supplierF(10)

	for msg := range g.C {
		fmt.Println(msg)
	}

}
Output:

10
20

func (*Generator) Next

func (g *Generator) Next() (msg any, ok bool)

Next behaves like an iterator, i.e. it can be used in a for loop. It's a grammar sugar for chan

Example
package main

import (
	"fmt"

	"github.com/searKing/golang/go/go/generator"
)

func main() {
	g := func(i int) *generator.Generator {
		return generator.GeneratorFunc(func(yield generator.Yield) {
			if !yield(i) {
				return
			}
			if !yield(i + 10) {
				return
			}
		})
	}

	gen := g(10)

	for {
		msg, ok := gen.Next()
		if !ok {
			return
		}
		fmt.Println(msg)
	}

}
Output:

10
20

func (*Generator) Stop

func (g *Generator) Stop() bool

Stop prevents the Generator from firing, with the channel drained. Stop ensures the channel is empty after a call to Stop. It returns true if the call stops the generator, false if the generator has already expired or been stopped. Stop does not close the channel, to prevent a read from the channel succeeding incorrectly.

This cannot be done concurrent to other receives from the Generator's channel.

For a generator created with GeneratorFuncWithSupplier(supplierC, f), if t.Stop returns false, then the generator has already expired and the function f has been started in its own goroutine; Stop does not wait for f to complete before returning. If the caller needs to know whether f is completed, it must coordinate with f explicitly.

func (*Generator) Stopped

func (g *Generator) Stopped() bool

func (*Generator) StoppedC

func (g *Generator) StoppedC() context.Context

func (*Generator) Yield

func (g *Generator) Yield(supplierC chan<- any) Yield

Yield is a grammar sugar for data src of generator ok returns true if msg sent; false if consume canceled If a function contains at least one yield statement (it may contain other yield or return statements), it becomes a generator function. Both yield and return will return some value from a function. The difference is that, while a return statement terminates a function entirely, yield statement pauses the function saving all its states and later continues from there on successive calls.

type Yield

type Yield func(msg any) (ok bool)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL