Python 风格的生成器实现为通道:过早阅读

问题描述 投票:0回答:1

我尝试使用以下通道实现 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()
正常工作?

go generator channel
1个回答
0
投票

这个:

r := make([]int, 5)

将初始化一个包含 5 个元素的切片,全部为 0。然后您将再向其中添加 5 个元素。您的程序正在读取前 5 个零元素。

用途:

r:=make([]int,0,5)

© www.soinside.com 2019 - 2024. All rights reserved.