首頁 > 後端開發 > Golang > Go 生成器關閉通道的責任該如何處理?

Go 生成器關閉通道的責任該如何處理?

Mary-Kate Olsen
發布: 2024-12-08 11:56:17
原創
293 人瀏覽過

How Should Responsibility for Closing Channels in Go Generators Be Handled?

使用 Yield 的生成器的慣用實現

在 Go 中,使用 Yield 實現生成器通常是透過 goroutine 和通道的組合來實現的。生成器函數會建立一個透過通道產生值的 goroutine,消費者函數在 for-range 循環中從通道接收這些值。

關閉通道的職責

根據Go 慣用語中,關閉通道的責任落在了生成器函數上。由於生成器知道迭代何時完成,因此它應該關閉通道,以向消費者發出信號,表明不會再收到任何值。

使用Caller Deferring Close() 修改程式碼

在修改後的程式碼中,您已正確地將關閉通道的責任放在呼叫者身上,而不是在生成器函數中關閉它。但是,您還應該刪除 main() 函數中的 close() 調用,因為關閉已經關閉的通道是不正確的。

package main

import (
    "./lib"
    "fmt"
)

var (
    fruits  = []string{"apple", "banana", "cherry", "durian"}
    banned = "durian"
)

func main() {
    channel := lib.PermutateWithChannel(fruits)
    defer close(channel) // Defer closing the channel

    for myFruits := range channel {
        fmt.Println(myFruits)
        if myFruits[0] == banned {
            break // Break from the loop instead of closing the channel
        }
    }
}
登入後複製

關閉已關閉通道的負面副作用

當呼叫者關閉通道時,任何後續嘗試向其發送值都會導致運行時恐慌。這是因為通道被標記為關閉,發送到關閉的通道是非法的。然而,除了終止嘗試發送值的 goroutine 之外,這種恐慌不會產生任何負面影響。

僅接收通道返回類型

限制庫函數返回的通道接收-only,同時仍然允許調用者關閉它,您可以引入一種新類型來包裝通道並僅公開僅接收通道:

type ReceiveOnlyChannel <-chan []string

func NewReceiveOnlyChannel(channel <-chan []string) *ReceiveOnlyChannel {
    return (*ReceiveOnlyChannel)(&channel)
}

func PermutateWithChannel(strings []string) *ReceiveOnlyChannel {
    // ... (same as before, except it returns ReceiveOnlyChannel)
}
登入後複製

透過將通道包裝在新類型中,您可以將其可存取性限制為僅接收操作,同時仍允許呼叫者透過包裝類型的Close()方法關閉它。

以上是Go 生成器關閉通道的責任該如何處理?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板