我尝试使用以下通道实现 Python 风格的生成器 this:
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
}
有机会向频道发送任何内容。 这不适用于第一种情况,因为调用
main()
时,r
goroutine 需要一些时间为 append()
切片重新分配空间。
请告知如何调整我的代码以使
Iterate()
正常工作?
这个:
r := make([]int, 5)
将初始化一个包含 5 个元素的切片,全部为 0。然后您将再向其中添加 5 个元素。您的程序正在读取前 5 个零元素。
用途:
r:=make([]int,0,5)