我有这个,我相信它接近按预期工作。我想做的是在一个序列上进行范围,但能够自己异步调用下一个项目
同步:
for r := range even.Sequence() {
if !r.Done {
r.Contnue()
}
}
或异步:
for r := range even.Sequence() {
go func(){
if !r.Done {
r.Contnue()
}
}()
}
这是 main 中的完整代码:
package main
import "fmt"
type HasNext[T any] interface {
Next() (bool, T)
}
type Nexter[T int] struct {
Val int
End int
}
type Ret struct {
Done bool
Value int
Contnue func()
}
func (n *Nexter[int]) Sequence() chan Ret {
var c = make(chan Ret)
even := newEven()
var x func()
x = func() {
fmt.Println("got here 3")
<-c
fmt.Println("got here 4")
fmt.Println("got here 5")
var b, v = even.Next()
c <- Ret{b, v, x}
if b {
close(c)
}
}
go func() {
var b, v = even.Next()
fmt.Println("got here 1")
c <- Ret{b, v, x}
fmt.Println("got here 2")
}()
return c
}
func (n *Nexter[int]) Next() (bool, int) {
n.Val = n.Val + 1
if n.Val > n.End {
return true, int(n.Val)
}
return false, int(n.Val)
}
func newEven() *Nexter[int] {
n := 0
return &Nexter[int]{n, 5}
}
func main() {
even := newEven()
for r := range even.Sequence() {
fmt.Println("value:", r.Value)
if !r.Done {
fmt.Println("continuing...")
r.Contnue()
}
}
}
但目前我得到这个输出:
got here 1 got here 2 value: 1 continuing... got here 3 fatal error: all goroutines are asleep - deadlock! goroutine 1 [chan receive]: main.main() /Users/me/codes/vibeirl/wss/test/iterator/main.go:83 +0x66
很明显它在某个地方陷入僵局,但不确定在哪里/如何准确
让它工作,我试图自己从通道中读取数据,但意识到(显然)范围本质上是从通道中读取的:
package main
import (
"fmt"
"time"
)
type HasNext[T any] interface {
Next() (bool, T)
}
type Nexter[T int] struct {
Val int
End int
}
type Ret struct {
Done bool
Value int
Contnue func()
}
func (n *Nexter[int]) Sequence() chan Ret {
var c = make(chan Ret, 1)
even := newEven()
var isClosed = false
var x func()
x = func() {
if isClosed {
fmt.Println("warning channel closed")
return
}
var b, v = even.Next()
if b {
isClosed = true
}
c <- Ret{b, v, x}
if b {
close(c)
}
}
go func() {
var b, v = even.Next()
c <- Ret{b, v, x}
}()
return c
}
func (n *Nexter[int]) Next() (bool, int) {
n.Val = n.Val + 1
if n.Val >= n.End {
return true, int(n.Val)
}
return false, int(n.Val)
}
func newEven() *Nexter[int] {
n := 0
return &Nexter[int]{n, 5}
}
func main() {
even := newEven()
for r := range even.Sequence() {
time.Sleep(time.Millisecond * 500)
fmt.Println("value:", r.Value)
if !r.Done {
r.Contnue()
}
}
}
我想知道一些事情 - isClosed 是否需要用锁来保护,但对我来说要弄清楚如何做到这一点并不容易