История изменений
Исправление kaldeon, (текущая версия) :
package main
func mkchan[T any](arr []T) <-chan T {
ch := make(chan T)
go func() {
defer close(ch)
for _, n := range arr {
ch <- n
}
}()
return ch
}
func sendout[T any](input <-chan T, cond func(v T) bool) (<-chan T, <-chan T) {
var (
west = make(chan T)
east = make(chan T)
)
var westclosed, eastclosed bool
go func() {
var (
westread = make(chan bool)
eastread = make(chan bool)
)
defer close(westread)
defer close(eastread)
var nwest, neast int
for n := range input {
if cond(n) {
nwest++
go func() {
west <- n
westread <- true
}()
} else {
neast++
go func() {
east <- n
eastread <- true
}()
}
}
for nwest != 0 || neast != 0 {
select {
case <-westread:
nwest--
case <-eastread:
neast--
}
if nwest == 0 && !westclosed {
westclosed = true
close(west)
}
if neast == 0 && !eastclosed {
eastclosed = true
close(east)
}
}
}()
return west, east
}
func main() {
arr := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
cond := func(n int) bool { return n%2 == 0 }
west, east := sendout(mkchan(arr), cond)
for n := range west {
println(n)
}
for n := range east {
println(n)
}
}
Исходная версия kaldeon, :
package main
func mkchan[T any](arr []T) <-chan T {
ch := make(chan T)
go func() {
defer close(ch)
for _, n := range arr {
ch <- n
}
}()
return ch
}
func sendout[T any](input <-chan T, cond func(v T) bool) (<-chan T, <-chan T) {
var (
west = make(chan T)
east = make(chan T)
)
var westclosed, eastclosed bool
go func() {
var (
westread = make(chan bool)
eastread = make(chan bool)
)
defer close(westread)
defer close(eastread)
var nwest, neast int
for n := range input {
if cond(n) {
nwest++
go func() {
west <- n
westread <- true
}()
} else {
neast++
go func() {
east <- n
eastread <- true
}()
}
}
for nwest != 0 || neast != 0 {
select {
case <-westread:
nwest--
case <-eastread:
neast--
}
if nwest == 0 && !westclosed {
westclosed = true
close(west)
}
if neast == 0 && !eastclosed {
eastclosed = true
close(east)
}
}
}()
return west, east
}
func main() {
arr := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
cond := func(n int) bool { return n%2 == 0 }
west, east := sendout(mkchan(arr), cond)
for n := range west {
println(n)
}
for n := range east {
println(n)
}
}