Documentation ¶
Overview ¶
Package chans は、チャネルに関するユーティリティが配置されています。
Index ¶
- func Bridge(done <-chan struct{}, chanCh <-chan <-chan interface{}) <-chan interface{}
- func Buffer(done <-chan struct{}, in <-chan interface{}, count int) <-chan []interface{}
- func Chain(done, base <-chan struct{}, next func(finishedTime time.Time)) <-chan struct{}
- func Chunk(done <-chan struct{}, in <-chan interface{}, count int) <-chan []interface{}
- func Concat(done <-chan struct{}, chList ...<-chan interface{}) <-chan interface{}
- func Enumerate(done <-chan struct{}, in <-chan interface{}) <-chan interface{}
- func FanIn(done <-chan struct{}, channels ...<-chan interface{}) <-chan interface{}
- func FanOut(done <-chan struct{}, in <-chan interface{}, workerCount int, ...) []<-chan struct{}
- func FanOutWg(done <-chan struct{}, in <-chan interface{}, workerCount int, ...) *sync.WaitGroup
- func Filter(done <-chan struct{}, in <-chan interface{}, predicate func(interface{}) bool) <-chan interface{}
- func ForEach(done <-chan struct{}, in ...interface{}) <-chan interface{}
- func FromIntCh(ch <-chan int) <-chan interface{}
- func FromStringCh(ch <-chan string) <-chan interface{}
- func Generator(done <-chan struct{}, in ...interface{}) <-chan interface{}
- func Interval(done <-chan struct{}, in <-chan interface{}, interval time.Duration) <-chan interface{}
- func Loop(done <-chan struct{}, start, end int) <-chan int
- func LoopInfinite(done <-chan struct{}) <-chan int
- func Map(done <-chan struct{}, in <-chan interface{}, fn MapFunc) <-chan interface{}
- func OrDone(done <-chan struct{}, in <-chan interface{}) <-chan interface{}
- func RecvAny(chs ...chan interface{}) (chosen int, v interface{}, ok bool)
- func Repeat(done <-chan struct{}, values ...interface{}) <-chan interface{}
- func RepeatFn(done <-chan struct{}, fn func() interface{}) <-chan interface{}
- func Select(chs ...chan interface{}) (chosen int, v interface{}, ok bool)
- func Skip(done <-chan struct{}, in <-chan interface{}, count int) <-chan interface{}
- func SkipWhile(done <-chan struct{}, in <-chan interface{}, value interface{}) <-chan interface{}
- func SkipWhileFn(done <-chan struct{}, in <-chan interface{}, fn func() interface{}) <-chan interface{}
- func Take(done <-chan struct{}, in <-chan interface{}, count int) <-chan interface{}
- func TakeWhile(done <-chan struct{}, in <-chan interface{}, value interface{}) <-chan interface{}
- func TakeWhileFn(done <-chan struct{}, in <-chan interface{}, fn func() interface{}) <-chan interface{}
- func Tee(done <-chan struct{}, in <-chan interface{}) (<-chan interface{}, <-chan interface{})
- func ToInt(done <-chan struct{}, in <-chan interface{}, failedValue int) <-chan int
- func ToString(done <-chan struct{}, in <-chan interface{}, failedValue string) <-chan string
- func WhenAll(channels ...<-chan struct{}) <-chan struct{}
- func WhenAny(channels ...<-chan struct{}) <-chan struct{}
- type IterValue
- type MapFunc
- type MapValue
- type SelectValue
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Bridge ¶ added in v0.1.5
func Bridge(done <-chan struct{}, chanCh <-chan <-chan interface{}) <-chan interface{}
Bridge -- 指定されたチャネルのシーケンスを順に消費していく単一のチャネルを返します。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() chSeq := make(chan (<-chan interface{})) go func() { defer close(chSeq) chSeq <- chans.Generator(procCtx.Done(), 1, 2, 3) chSeq <- chans.Generator(procCtx.Done(), 4, 5, 6) }() for v := range chans.Bridge(procCtx.Done(), chSeq) { fmt.Println(v) } }
Output: 1 2 3 4 5 6
func Buffer ¶ added in v0.2.18
func Buffer(done <-chan struct{}, in <-chan interface{}, count int) <-chan []interface{}
Buffer は、入力を指定した件数分に束ねてデータを返すチャネルを生成します.
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() var ( data = []interface{}{1, 2, 3, 4, 5, 6, 7} count = 3 ) numbers := chans.Generator(procCtx.Done(), data...) chunks := chans.Buffer(procCtx.Done(), numbers, count) for chunk := range chunks { fmt.Println(chunk) } }
Output: [1 2 3] [4 5 6] [7]
func Chain ¶ added in v0.2.14
Chain -- 指定された base チャネルがクローズした後に next で指定された関数を呼び出します.
done チャネルがクローズした場合、 next は実行されません。
Example ¶
package main import ( "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { // functions var ( makeGoroutine = func() <-chan struct{} { ch := make(chan struct{}) go func() { defer close(ch) time.Sleep(100 * time.Millisecond) fmt.Println("base") }() return ch } ) // channels var ( done = make(chan struct{}) base = makeGoroutine() ) defer close(done) chain1 := chans.Chain(done, base, func(t time.Time) { fmt.Println("chain-1") }) chain2 := chans.Chain(done, chain1, func(t time.Time) { fmt.Println("chain-2") }) <-chans.WhenAll(base, chain1, chain2) }
Output: base chain-1 chain-2
func Chunk ¶ added in v0.3.0
func Chunk(done <-chan struct{}, in <-chan interface{}, count int) <-chan []interface{}
Chunkは、入力を指定した件数分に束ねてデータを返すチャネルを生成します.
Buffer関数のエイリアスです。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() numbers := chans.Generator(procCtx.Done(), 1, 2, 3, 4, 5, 6, 7) chunks := chans.Chunk(procCtx.Done(), numbers, 3) for chunk := range chunks { fmt.Println(chunk) } }
Output: [1 2 3] [4 5 6] [7]
func Concat ¶ added in v0.1.7
func Concat(done <-chan struct{}, chList ...<-chan interface{}) <-chan interface{}
Concat -- 指定されたチャネルのシーケンスを順に消費していく単一のチャネルを返します。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() nums1 := chans.Generator(procCtx.Done(), 1, 2, 3) nums2 := chans.Generator(procCtx.Done(), 4, 5, 6) for v := range chans.Concat(procCtx.Done(), nums1, nums2) { fmt.Println(v) } }
Output: 1 2 3 4 5 6
func Enumerate ¶ added in v0.2.0
func Enumerate(done <-chan struct{}, in <-chan interface{}) <-chan interface{}
Enumerate -- 指定された入力チャネルの要素に対してインデックスを付与したデータを返すチャネルを生成します。
戻り値のチャネルから取得できるデータ型は、*chans.IterValue となっています。
for e := range chans.Enumerate(done, inCh) { if v, ok := e.(*IterValue); ok { // v.Index でインデックス、 v.Value で値が取得できる } }
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() numbers := chans.Generator(procCtx.Done(), 9, 8, 7) values := chans.Enumerate(procCtx.Done(), numbers) for e := range values { if v, ok := e.(*chans.IterValue); ok { fmt.Printf("%d:%v\n", v.Index, v.Value) } } }
Output: 0:9 1:8 2:7
func FanIn ¶ added in v0.1.5
func FanIn(done <-chan struct{}, channels ...<-chan interface{}) <-chan interface{}
FanIn -- 指定されたチャネルリストをファンインするチャネルを返します。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() numStream1 := chans.Generator(procCtx.Done(), 1, 2, 3) numStream2 := chans.Generator(procCtx.Done(), 4, 5, 6) for v := range chans.FanIn(procCtx.Done(), numStream1, numStream2) { fmt.Println(v) } }
Output: 4 1 5 2 3 6
func FanOut ¶ added in v0.2.1
func FanOut(done <-chan struct{}, in <-chan interface{}, workerCount int, callback func(interface{})) []<-chan struct{}
FanOut -- 指定されたチャネルの処理を指定されたワーカーの数でファンアウトします。
チャネルからデータを取得するたびに引数 callback が呼ばれます。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() var ( nums = chans.Generator(procCtx.Done(), 1, 2, 3, 4, 5, 6) callback = func(v interface{}) { fmt.Println(v) } ) dones := chans.FanOut(procCtx.Done(), nums, 3, callback) <-chans.WhenAll(dones...) }
Output: 4 1 2 3 6 5
func FanOutWg ¶ added in v0.2.2
func FanOutWg(done <-chan struct{}, in <-chan interface{}, workerCount int, callback func(interface{})) *sync.WaitGroup
FanOutWg -- FanOut() の sync.WaitGroup を返す版です。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() var ( nums = chans.Generator(procCtx.Done(), 1, 2, 3, 4, 5, 6) callback = func(v interface{}) { fmt.Println(v) } ) wg := chans.FanOutWg(procCtx.Done(), nums, 3, callback) wg.Wait() }
Output: 4 1 2 3 6 5
func Filter ¶ added in v0.2.0
func Filter(done <-chan struct{}, in <-chan interface{}, predicate func(interface{}) bool) <-chan interface{}
Filter -- 入力データチャネル in から取得したデータを predicate に渡して 真 となったデータを返すチャネルを生成します。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() var ( numbers = chans.Generator(procCtx.Done(), 1, 2, 3, 4, 5) predicate = func(v interface{}) bool { if i, ok := v.(int); ok { return i%2 == 0 } return false } ) for v := range chans.Filter(procCtx.Done(), numbers, predicate) { fmt.Println(v) } }
Output: 2 4
func ForEach ¶ added in v0.2.0
func ForEach(done <-chan struct{}, in ...interface{}) <-chan interface{}
ForEach -- 指定されたデータを出力するチャネルを生成します。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() for v := range chans.ForEach(procCtx.Done(), 1, 2, 3) { fmt.Println(v) } }
Output: 1 2 3
func FromIntCh ¶ added in v0.2.0
func FromIntCh(ch <-chan int) <-chan interface{}
FromIntCh -- chan int を chan interface{} に変換します。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() var ints <-chan int = func(pCtx context.Context) <-chan int { ctx, cxl := context.WithCancel(pCtx) ch := make(chan int) go func() { defer cxl() defer close(ch) for i := 0; i < 3; i++ { select { case <-ctx.Done(): return case ch <- i: } } }() return ch }(procCtx) var items <-chan interface{} = chans.FromIntCh(ints) for v := range items { fmt.Println(v) } }
Output: 0 1 2
func FromStringCh ¶ added in v0.2.0
func FromStringCh(ch <-chan string) <-chan interface{}
FromStringCh -- chan string を chan interface{} に変換します。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() var strs <-chan string = func(pCtx context.Context) <-chan string { ctx, cxl := context.WithCancel(pCtx) ch := make(chan string) go func() { defer cxl() defer close(ch) for _, s := range []string{"h", "e", "l", "l", "o"} { select { case <-ctx.Done(): case ch <- s: } } }() return ch }(procCtx) var items <-chan interface{} = chans.FromStringCh(strs) for v := range items { fmt.Println(v) } }
Output: h e l l o
func Generator ¶ added in v0.2.5
func Generator(done <-chan struct{}, in ...interface{}) <-chan interface{}
Generator -- 指定されたデータを出力するチャネルを生成します。
ForEach関数のエイリアスです。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() numbers := chans.Generator(procCtx.Done(), 1, 2, 3, 4, 5) for v := range numbers { fmt.Println(v) } }
Output: 1 2 3 4 5
func Interval ¶ added in v0.2.0
func Interval(done <-chan struct{}, in <-chan interface{}, interval time.Duration) <-chan interface{}
Interval -- 指定した間隔でデータを出力していくチャネルを生成します。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() var ( numbers = chans.Generator(procCtx.Done(), 1, 2, 3, 4, 5) withInterval = chans.Interval(procCtx.Done(), numbers, 5*time.Millisecond) ) begin := time.Now() for range withInterval { // no-op } elapsed := time.Since(begin) fmt.Printf("elapsed <= 35msec: %v\n", elapsed < 50*time.Millisecond) }
Output: elapsed <= 35msec: true
func Loop ¶ added in v0.2.0
Loop -- 指定された開始と終了の間、データを返し続けるチャネルを生成します。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 10*time.Millisecond) ) defer mainCxl() defer procCxl() for v := range chans.Loop(procCtx.Done(), 0, 5) { fmt.Println(v) } }
Output: 0 1 2 3 4
func LoopInfinite ¶ added in v0.2.0
func LoopInfinite(done <-chan struct{}) <-chan int
LoopInfinite -- 無限にループして、データを返し続けるチャネルを生成します。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { // contexts var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 10*time.Millisecond) ) defer mainCxl() defer procCxl() // channels var ( infinite = chans.LoopInfinite(procCtx.Done()) takes = chans.Take(procCtx.Done(), chans.FromIntCh(infinite), 5) ) for v := range takes { fmt.Println(v) } }
Output: 0 1 2 3 4
func Map ¶ added in v0.2.0
func Map(done <-chan struct{}, in <-chan interface{}, fn MapFunc) <-chan interface{}
Map -- 関数 fn を入力チャネル in の各要素に適用した結果を返すチャネルを生成します。
戻り値のチャネルから取得できるデータ型は、*chans.MapValue となっています。
for m := range chans.Map(done, inCh, fn) { if v, ok := m.(*chans.MapValue); ok { // v.Before で元の値、 v.After で適用後の値が取得できる } }
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() var ( numbers = chans.Generator(procCtx.Done(), 1, 2, 3) fn = func(original interface{}) (after interface{}) { if i, ok := original.(int); ok { return i * 2 } return nil } ) for v := range chans.Map(procCtx.Done(), numbers, fn) { if m, ok := v.(*chans.MapValue); ok { fmt.Printf("%v,%v\n", m.Before, m.After) } } }
Output: 1,2 2,4 3,6
func OrDone ¶ added in v0.1.5
func OrDone(done <-chan struct{}, in <-chan interface{}) <-chan interface{}
OrDone -- 指定された終了チャネルと入力用チャネルのどちらかが閉じたら閉じるチャネルを返します。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 1*time.Minute) genCtx, genCxl = context.WithCancel(mainCtx) ) defer mainCxl() defer procCxl() defer genCxl() inCh := chans.Generator(genCtx.Done(), "h", "e", "l", "l", "o") var result []interface{} for v := range chans.OrDone(procCtx.Done(), inCh) { func() { defer procCxl() result = append(result, v) }() } fmt.Printf("len(result) <= 2: %v", len(result) <= 2) }
Output: len(result) <= 2: true
func RecvAny ¶ added in v0.3.3
RecvAny -- 指定されたチャネルリストから一つ値を取得します。どのチャネルが選択されるかは非決定的です。
See: chans.Select
Example ¶
package main import ( "fmt" "github.com/devlights/gomy/chans" ) func main() { var ( ch1 = make(chan interface{}) ch2 = make(chan interface{}) ) defer close(ch1) defer close(ch2) go func() { ch1 <- 1 }() go func() { ch2 <- 2 }() _, v1, _ := chans.RecvAny(ch1, ch2) _, v2, _ := chans.RecvAny(ch1, ch2) fmt.Println(v1) fmt.Println(v2) }
Output: 1 2
func Repeat ¶ added in v0.1.5
func Repeat(done <-chan struct{}, values ...interface{}) <-chan interface{}
Repeat -- 指定した値を永遠と繰り返すチャネルを返します。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() repeats := chans.Repeat(procCtx.Done(), 1, 2, 3) takes := chans.Take(procCtx.Done(), repeats, 6) for v := range takes { fmt.Println(v) } }
Output: 1 2 3 1 2 3
func RepeatFn ¶ added in v0.1.5
func RepeatFn(done <-chan struct{}, fn func() interface{}) <-chan interface{}
RepeatFn -- 指定した関数を永遠と繰り返し、その戻り値を返すチャネルを返します。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() ch := make(chan interface{}) go func() { defer close(ch) for { for _, v := range []int{1, 2, 3} { select { case <-procCtx.Done(): return case ch <- v: } } } }() repeats := chans.RepeatFn(procCtx.Done(), func() interface{} { return <-ch }) takes := chans.Take(procCtx.Done(), repeats, 6) for v := range takes { fmt.Println(v) } }
Output: 1 2 3 1 2 3
func Select ¶ added in v0.3.3
Select -- 指定されたチャネルリストから一つ値を取得します。どのチャネルが選択されるかは非決定的です。
内部で reflect.Select() を呼び出しており、戻り値はそれに準じています。
REFERENCES:
- https://pkg.go.dev/reflect#Select
- https://pkg.go.dev/reflect#SelectCase
- https://dev.to/hgsgtk/handling-with-arbitrary-channels-by-reflectselect-4d5g
Example ¶
package main import ( "fmt" "github.com/devlights/gomy/chans" ) func main() { var ( ch1 = make(chan interface{}) ch2 = make(chan interface{}) ) defer close(ch1) defer close(ch2) go func() { ch1 <- 1 }() go func() { ch2 <- 2 }() _, v1, _ := chans.Select(ch1, ch2) _, v2, _ := chans.Select(ch1, ch2) fmt.Println(v1) fmt.Println(v2) }
Output: 1 2
func Skip ¶ added in v0.2.0
func Skip(done <-chan struct{}, in <-chan interface{}, count int) <-chan interface{}
Skip -- 指定した個数分、入力用チャネルから値をスキップするチャネルを返します。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() numbers := chans.Generator(procCtx.Done(), 1, 1, 1, 4, 5) items := chans.Skip(procCtx.Done(), numbers, 3) for v := range items { fmt.Println(v) } }
Output: 4 5
func SkipWhile ¶ added in v0.2.0
func SkipWhile(done <-chan struct{}, in <-chan interface{}, value interface{}) <-chan interface{}
SkipWhile -- 入力用チャネルから取得した値が指定した値と同一である間、値をスキップし続けるチャネルを返します。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() numbers := chans.Generator(procCtx.Done(), 1, 1, 1, 4, 5) items := chans.SkipWhile(procCtx.Done(), numbers, 1) for v := range items { fmt.Println(v) } }
Output: 4 5
func SkipWhileFn ¶ added in v0.2.0
func SkipWhileFn(done <-chan struct{}, in <-chan interface{}, fn func() interface{}) <-chan interface{}
SkipWhileFn -- 入力用チャネルから取得した値が指定した関数の戻り値と同一である間、値をスキップし続けるチャネルを返します。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() numbers := chans.Generator(procCtx.Done(), 1, 1, 1, 4, 5) items := chans.SkipWhileFn(procCtx.Done(), numbers, func() interface{} { return 1 }) for v := range items { fmt.Println(v) } }
Output: 4 5
func Take ¶ added in v0.1.5
func Take(done <-chan struct{}, in <-chan interface{}, count int) <-chan interface{}
Take -- 指定した個数分、入力用チャネルから値を取得するチャネルを返します。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() numbers := chans.ForEach(procCtx.Done(), 1, 2, 3, 4, 5) takes := chans.Take(procCtx.Done(), numbers, 3) for v := range takes { fmt.Println(v) } }
Output: 1 2 3
func TakeWhile ¶ added in v0.1.5
func TakeWhile(done <-chan struct{}, in <-chan interface{}, value interface{}) <-chan interface{}
TakeWhile -- 入力用チャネルから取得した値が指定した値と同一である間、値を取得し続けるチャネルを返します。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() numbers := chans.ForEach(procCtx.Done(), 1, 1, 1, 4, 1) takes := chans.TakeWhile(procCtx.Done(), numbers, 1) for v := range takes { fmt.Println(v) } }
Output: 1 1 1
func TakeWhileFn ¶ added in v0.1.5
func TakeWhileFn(done <-chan struct{}, in <-chan interface{}, fn func() interface{}) <-chan interface{}
TakeWhileFn -- 入力用チャネルから取得した値が指定した関数の戻り値と同一である間、値を取得し続けるチャネルを返します。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() numbers := chans.ForEach(procCtx.Done(), 1, 1, 1, 4, 1) takes := chans.TakeWhileFn(procCtx.Done(), numbers, func() interface{} { return 1 }) for v := range takes { fmt.Println(v) } }
Output: 1 1 1
func Tee ¶ added in v0.1.5
func Tee(done <-chan struct{}, in <-chan interface{}) (<-chan interface{}, <-chan interface{})
Tee -- Unix の tee コマンドのように一つの入力を2つに複製するチャネルを返します。
noinspection GoNilness
Example ¶
package main import ( "context" "fmt" "sync" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() numbers := chans.Generator(procCtx.Done(), 1) ch1, ch2 := chans.Tee(procCtx.Done(), numbers) var wg sync.WaitGroup for _, ch := range []<-chan interface{}{ch1, ch2} { wg.Add(1) go func(ch <-chan interface{}) { defer wg.Done() for v := range ch { fmt.Println(v) } }(ch) } wg.Wait() }
Output: 1 1
func ToInt ¶ added in v0.1.5
ToInt -- 入力用チャネルから値を取得し、数値に変換するチャネルを返します。
数値に変換することが出来なかった場合は、引数 failedValue を出力用チャネルに送ります。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() var ( gens <-chan interface{} = chans.Generator(procCtx.Done(), 1, 2) ints <-chan int = chans.ToInt(procCtx.Done(), gens, -1) ) for v := range ints { fmt.Println(v) } }
Output: 1 2
func ToString ¶ added in v0.1.5
ToString -- 入力用チャネルから値を取得し、文字列に変換するチャネルを返します。
文字列に変換することが出来なかった場合は、引数 failedValue を出力用チャネルに送ります。
Example ¶
package main import ( "context" "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { var ( rootCtx = context.Background() mainCtx, mainCxl = context.WithCancel(rootCtx) procCtx, procCxl = context.WithTimeout(mainCtx, 50*time.Millisecond) ) defer mainCxl() defer procCxl() var ( gens <-chan interface{} = chans.Generator(procCtx.Done(), "hello", "world") strs <-chan string = chans.ToString(procCtx.Done(), gens, "") ) for v := range strs { fmt.Println(v) } }
Output: hello world
func WhenAll ¶
func WhenAll(channels ...<-chan struct{}) <-chan struct{}
WhenAll -- 指定した1つ以上のチャネルの全てが閉じられたら、閉じるチャネルを返します。
チャネルを一つも渡さずに呼び出すと、既に close 済みのチャネルを返します。
Example ¶
package main import ( "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { fn := func(tlimit time.Duration) <-chan struct{} { done := make(chan struct{}) go func() { defer close(done) time.Sleep(tlimit) }() return done } done1 := fn(100 * time.Millisecond) done2 := fn(200 * time.Millisecond) done3 := fn(300 * time.Millisecond) start := time.Now() <-chans.WhenAll(done1, done2, done3) elapsed := time.Since(start) fmt.Printf("elapsed: about 300msec ==> %v\n", elapsed >= 299*time.Millisecond) }
Output: elapsed: about 300msec ==> true
func WhenAny ¶
func WhenAny(channels ...<-chan struct{}) <-chan struct{}
WhenAny -- 指定した1つ以上のチャネルのどれかが1つが閉じられたら、閉じるチャネルを返します。
チャネルを一つも渡さずに呼び出すと、既に close 済みのチャネルを返します。
Example ¶
package main import ( "fmt" "time" "github.com/devlights/gomy/chans" ) func main() { fn := func(tlimit time.Duration) <-chan struct{} { done := make(chan struct{}) go func() { defer close(done) time.Sleep(tlimit) }() return done } done1 := fn(100 * time.Millisecond) done2 := fn(200 * time.Millisecond) done3 := fn(300 * time.Millisecond) start := time.Now() <-chans.WhenAny(done1, done2, done3) elapsed := time.Since(start) fmt.Printf("elapsed: about 100msec ==> %v\n", elapsed <= 110*time.Millisecond) }
Output: elapsed: about 100msec ==> true
Types ¶
type IterValue ¶ added in v0.2.0
type IterValue struct { Index int // インデックス Value interface{} // 値 }
IterValue -- chans.Enumerate() にて利用されるデータ型です。
type MapFunc ¶ added in v0.2.0
type MapFunc func(interface{}) interface{}
MapFunc -- chans.Map にて利用されるチャネルの各要素に適用する関数です。
type MapValue ¶ added in v0.2.0
type MapValue struct { Before interface{} // 元の値 After interface{} // 適用後の値 }
MapValue -- chans.Map にて利用されるデータ型です。
type SelectValue ¶ added in v0.3.3
type SelectValue struct { Chosen int // 選択されたチャネルのインデックス Value interface{} // 受信した値 }
SelectValue -- chans.RecvAll() で利用されるデータ型です.
func RecvAll ¶ added in v0.3.3
func RecvAll(chs ...chan interface{}) []SelectValue
RecvAll -- 指定されたチャネルリストの全てから1つ値を取得して返却します。
Example ¶
package main import ( "fmt" "github.com/devlights/gomy/chans" ) func main() { var ( ch1 = make(chan interface{}) ch2 = make(chan interface{}) ) defer close(ch1) defer close(ch2) go func() { ch1 <- 1 }() go func() { ch2 <- 2 }() for _, v := range chans.RecvAll(ch1, ch2) { fmt.Printf("chosen:%d,value:%v\n", v.Chosen, v.Value) } }
Output: chosen:0,value:1 chosen:1,value:2
func (SelectValue) Eq ¶ added in v0.3.3
func (me SelectValue) Eq(other SelectValue) bool
Eq -- 同じデータかどうかを判定します.