Python-style generators implemented as channels: reading too early

王林
Release: 2024-02-08 23:06:17
forward
328 people have browsed it

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

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!

Question content

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])
    }
}
Copy after login

This works fine, the output is

0 0 true
1 1 true
2 2 true
3 3 true
4 4 true
Copy after login

But when I change

r := make([]int, 0)
Copy after login

to

r := make([]int, 5)
Copy after login
Copy after login

The results are different:

0 0 true
1 0 false
2 0 false
3 0 false
4 0 false
Copy after login

I know that in the second case c.Iterate() before starting reading from the channel

go func() {
        for _, v := range c.content {
            ch <- v
        }
Copy after login

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?

Solution

This:

r := make([]int, 5)
Copy after login
Copy after login

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!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!