Skip to content

Instantly share code, notes, and snippets.

@DeedleFake
Created July 20, 2021 19:57
Show Gist options
  • Save DeedleFake/f1425102a0879b83c41f7b22276208cc to your computer and use it in GitHub Desktop.
Save DeedleFake/f1425102a0879b83c41f7b22276208cc to your computer and use it in GitHub Desktop.
Experimental Kotlin Flow System in Go
package main
import (
"context"
"fmt"
)
type Producer[T any] interface {
Produce(ctx context.Context) (T, bool)
}
type sliceProducer[T any] struct {
s []T
i int
}
func (s *sliceProducer[T]) Produce(ctx context.Context) (v T, ok bool) {
if s.i >= len(s.s) {
return v, false
}
i := s.i
s.i++
return s.s[i], true
}
type unchangedFilter[T comparable] struct {
p Producer[T]
prev *T
}
func (f *unchangedFilter[T]) Produce(ctx context.Context) (v T, ok bool) {
for {
v, ok = f.p.Produce(ctx)
if !ok {
return v, false
}
if (f.prev != nil) && (*f.prev == v) {
continue
}
f.prev = &v
return v, true
}
}
type Flow[T any] struct {
p Producer[T]
}
func NewFlow[T any](p Producer[T]) Flow[T] {
return Flow[T]{p: p}
}
func FlowOf[T any](v ...T) Flow[T] {
return Flow[T]{p: &sliceProducer[T]{s: v}}
}
func FilterUnchanged[T comparable](f Flow[T]) Flow[T] {
return Flow[T]{p: &unchangedFilter[T]{p: f.p}}
}
func (flow Flow[T]) Collect(ctx context.Context, f func(T)) {
for {
select {
case <-ctx.Done():
return
default:
v, ok := flow.p.Produce(ctx)
if !ok {
return
}
f(v)
}
}
}
func main() {
FilterUnchanged(FlowOf(3, 5, 5, 2, 2, 2)).Collect(context.Background(), func(v int) {
fmt.Println(v)
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment