Maison >développement back-end >Golang >Générateurs de style Python implémentés sous forme de canaux : lecture trop tôt

Générateurs de style Python implémentés sous forme de canaux : lecture trop tôt

王林
王林avant
2024-02-08 23:06:17367parcourir

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

php小编柚子带来了一篇关于通道实现的Python风格生成器的文章。在这篇文章中,我们将介绍过早阅读的概念,以及如何使用通道来实现Python风格的生成器。通过这种方式,我们可以在PHP中使用类似于Python中的生成器语法,提供更加灵活和高效的编程体验。无论你是PHP开发者还是对生成器感兴趣的人,这篇文章都会为你提供有价值的知识和实用的技巧。让我们一起来探索这个有趣的主题吧!

问题内容

我尝试使用以下通道实现 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
        }

有机会向频道发送任何内容。 这不适用于第一种情况,因为当调用 append() 时,main() goroutine 需要一些时间来为 r 切片重新分配空间。

请告知如何调整我的代码以使 Iterate() 正常工作?

解决方法

这个:

r := make([]int, 5)

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

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer