首頁  >  文章  >  後端開發  >  作為通道實現的 Python 風格生成器:過早閱讀

作為通道實現的 Python 風格生成器:過早閱讀

王林
王林轉載
2024-02-08 23:06:17330瀏覽

作为通道实现的 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)

以上是作為通道實現的 Python 風格生成器:過早閱讀的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除