Documentation ¶
Overview ¶
Package chans は、チャネルに関するユーティリティが配置されています。
Index ¶
- func Bridge[T any](done <-chan struct{}, chanCh <-chan <-chan T) <-chan T
- func Buffer[T any](done <-chan struct{}, in <-chan T, count int) <-chan []T
- func Chain(done, base <-chan struct{}, next func(finished time.Time)) <-chan struct{}
- func Chunk[T any](done <-chan struct{}, in <-chan T, count int) <-chan []T
- func Concat[T any](done <-chan struct{}, chList ...<-chan T) <-chan T
- func Convert[F any, T any](done <-chan struct{}, in <-chan F, fn func(F) T) <-chan T
- func Enumerate[T any](done <-chan struct{}, in <-chan T) <-chan *IterValue[T]
- func FanIn[T any](done <-chan struct{}, channels ...<-chan T) <-chan T
- func FanOut[T any](done <-chan struct{}, in <-chan T, workerCount int, callback func(T)) []<-chan struct{}
- func FanOutWg[T any](done <-chan struct{}, in <-chan T, workerCount int, callback func(T)) *sync.WaitGroup
- func Filter[T any](done <-chan struct{}, in <-chan T, predicate func(T) bool) <-chan T
- func ForEach[T any](done <-chan struct{}, in ...T) <-chan T
- func FromIntCh(ch <-chan int) <-chan any
- func FromStringCh(ch <-chan string) <-chan any
- func Generator[T any](done <-chan struct{}, in ...T) <-chan T
- func Interval[T any](done <-chan struct{}, in <-chan T, interval time.Duration) <-chan T
- func Loop(done <-chan struct{}, start, end int) <-chan int
- func LoopInfinite(done <-chan struct{}) <-chan int
- func Map[T any](done <-chan struct{}, in <-chan T, fn MapFunc[T]) <-chan *MapValue[T]
- func OrDone[T any](done <-chan struct{}, in <-chan T) <-chan T
- func RecvAny(chs ...chan interface{}) (chosen int, v interface{}, ok bool)
- func Repeat[T any](done <-chan struct{}, values ...T) <-chan T
- func RepeatFn[T any](done <-chan struct{}, fn func() T) <-chan T
- func Select(chs ...chan interface{}) (chosen int, v interface{}, ok bool)
- func Skip[T any](done <-chan struct{}, in <-chan T, count int) <-chan T
- func SkipWhile[T comparable](done <-chan struct{}, in <-chan T, value T) <-chan T
- func SkipWhileFn[T comparable](done <-chan struct{}, in <-chan T, fn func() T) <-chan T
- func Take[T any](done <-chan struct{}, in <-chan T, count int) <-chan T
- func TakeWhile[T comparable](done <-chan struct{}, in <-chan T, value T) <-chan T
- func TakeWhileFn[T comparable](done <-chan struct{}, in <-chan T, fn func() T) <-chan T
- func Tee[T any](done <-chan struct{}, in <-chan T) (<-chan T, <-chan T)
- func ToInt[T any](done <-chan struct{}, in <-chan T, failedValue int) <-chan int
- func ToString[T any](done <-chan struct{}, in <-chan T, failedValue string) <-chan string
- func WhenAll[T any](channels ...<-chan T) <-chan T
- func WhenAny[T any](channels ...<-chan T) <-chan T
- 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[T any](done <-chan struct{}, chanCh <-chan <-chan T) <-chan T
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 int)) 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
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
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[T any](done <-chan struct{}, chList ...<-chan T) <-chan T
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 Convert ¶ added in v0.4.2
Convert -- 入力用チャネルから値を取得し変換するチャネルを返します。
Example ¶
package main import ( "context" "fmt" "strconv" "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 ( done = procCtx.Done() numbers = chans.Generator(done, 1, 2, 3) converted = chans.Convert(done, numbers, func(v int) string { return strconv.Itoa(v) }) ) for v := range converted { fmt.Printf("[%T]%q\n", v, v) } }
Output: [string]"1" [string]"2" [string]"3"
func Enumerate ¶ added in v0.2.0
Enumerate -- 指定された入力チャネルの要素に対してインデックスを付与したデータを返すチャネルを生成します。
戻り値のチャネルから取得できるデータ型は、*chans.IterValue となっています。
for v := range chans.Enumerate(done, inCh) { // 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 v := range values { 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[T any](done <-chan struct{}, channels ...<-chan T) <-chan T
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[T any](done <-chan struct{}, in <-chan T, workerCount int, callback func(T)) []<-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 int) { 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[T any](done <-chan struct{}, in <-chan T, workerCount int, callback func(T)) *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 int) { 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
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 int) bool { return v%2 == 0 } ) for v := range chans.Filter(procCtx.Done(), numbers, predicate) { fmt.Println(v) } }
Output: 2 4
func ForEach ¶ added in v0.2.0
func ForEach[T any](done <-chan struct{}, in ...T) <-chan T
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
FromIntCh -- chan int を chan any に変換します。
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
FromStringCh -- chan string を chan any に変換します。
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[T any](done <-chan struct{}, in ...T) <-chan T
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
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
Map -- 関数 fn を入力チャネル in の各要素に適用した結果を返すチャネルを生成します。
戻り値のチャネルから取得できるデータ型は、*chans.MapValue となっています。
for v := range chans.Map(done, inCh, fn) { // 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 int) (after int) { return original * 2 } ) for v := range chans.Map(procCtx.Done(), numbers, fn) { fmt.Printf("%v,%v\n", v.Before, v.After) } }
Output: 1,2 2,4 3,6
func OrDone ¶ added in v0.1.5
func OrDone[T any](done <-chan struct{}, in <-chan T) <-chan T
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[T any](done <-chan struct{}, values ...T) <-chan T
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[T any](done <-chan struct{}, fn func() T) <-chan T
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
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[T comparable](done <-chan struct{}, in <-chan T, value T) <-chan T
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[T comparable](done <-chan struct{}, in <-chan T, fn func() T) <-chan T
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() int { return 1 }) for v := range items { fmt.Println(v) } }
Output: 4 5
func Take ¶ added in v0.1.5
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[T comparable](done <-chan struct{}, in <-chan T, value T) <-chan T
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[T comparable](done <-chan struct{}, in <-chan T, fn func() T) <-chan T
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() int { return 1 }) for v := range takes { fmt.Println(v) } }
Output: 1 1 1
func Tee ¶ added in v0.1.5
func Tee[T any](done <-chan struct{}, in <-chan T) (<-chan T, <-chan T)
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 int{ch1, ch2} { wg.Add(1) go func(ch <-chan int) { 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 int = 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 string = 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[T any](channels ...<-chan T) <-chan T
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[T any](channels ...<-chan T) <-chan T
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 MapFunc ¶ added in v0.2.0
type MapFunc[T any] func(T) T
MapFunc -- chans.Map にて利用されるチャネルの各要素に適用する関数です。
type MapValue ¶ added in v0.2.0
type MapValue[T any] struct { Before T // 元の値 After T // 適用後の値 }
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 -- 同じデータかどうかを判定します.