我try 使用this之后的通道来实现Python风格的生成器:
package main
import (
"fmt"
)
type ContainerIterable[T any] struct {
content []T
}
func NewContainerIterable[T any]() *ContainerIterable[T] {
return &ContainerIterable[T]{content: make([]T, 0)}
}
func (c *ContainerIterable[T]) Iterate() chan T {
ch := make(chan T)
go func() {
for _, v := range c.content {
ch <- v
}
close(ch)
}()
return ch
}
func (c *ContainerIterable[T]) Add(e T) {
c.content = append(c.content, e)
}
func main() {
c := NewContainerIterable[int]()
for i := 0; i < 5; i++ {
c.Add(i)
}
r := make([]int, 0)
for v := range c.Iterate() {
r = append(r, v)
}
for i := 0; i < 5; i++ {
fmt.Println(i, r[i], i == r[i])
}
}
它工作得很好,输出是
0 0 true
1 1 true
2 2 true
3 3 true
4 4 true
然而,当我改变时
r := make([]int, 0)
至
r := make([]int, 5)
结果是不同的:
0 0 true
1 0 false
2 0 false
3 0 false
4 0 false
我理解在第二种情况下,c.Iterate()
在之前开始从频道读取
go func() {
for _, v := range c.content {
ch <- v
}
has a chance 至 send anything 至 channel.
This does not apply 至 the first case since main()
goroutine takes some time 至 reallocate space for r
slice when append()
is invoked.
Please advise how 至 adjust my code 至 make Iterate()
work properly?