Home > Article > Backend Development > Python-style generators implemented as channels: reading too early
php editor Youzi brought an article about the Python style generator for channel implementation. In this post, we'll introduce the concept of premature reading and how to use channels to implement Python-style generators. In this way, we can use generator syntax in PHP similar to that in Python, providing a more flexible and efficient programming experience. Whether you are a PHP developer or someone interested in generators, this article will provide you with valuable knowledge and practical tips. Let’s explore this interesting topic together!
I try to implement a Python-style generator using the following channel:
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]) } }
This works fine, the output is
0 0 true 1 1 true 2 2 true 3 3 true 4 4 true
But when I change
r := make([]int, 0)
to
r := make([]int, 5)
The results are different:
0 0 true 1 0 false 2 0 false 3 0 false 4 0 false
I know that in the second case c.Iterate()
before starting reading from the channel
go func() { for _, v := range c.content { ch <- v }
Opportunity to send any content to the channel.
This does not apply to the first case because when append()
is called, the main()
goroutine takes some time to reallocate space for the r
slice.
Please advise how to adjust my code to make Iterate()
work properly?
This:
r := make([]int, 5)
will initialize a slice containing 5 elements, all 0. You will then add 5 more elements to it. Your program is reading the first 5 zero elements.
Use: r:=make([]int,0,5)
The above is the detailed content of Python-style generators implemented as channels: reading too early. For more information, please follow other related articles on the PHP Chinese website!