尝试向关闭的通道插入值时避免恐慌

package main


import (

    "fmt"

    "time"

)


func fib() chan int {

    c := make(chan int)


    go func() {

        c <- 0

        c <- 1


        n, m := 0, 1

        for {

            temp := n + m

            n = m

            m = temp

            c <- m // This results in panic, when the channel is closed

        }

    }()


    return c

}


func main() {

    start := time.Now()

    var lastFib int

    c := fib()


    for i := 0; i != 1000000; i++ {

        lastFib = <-c

    }


    close(c)

    fmt.Println(lastFib)

    fmt.Println(time.Now().Sub(start))

}

以最惯用的方式,当通道关闭时,如何避免 goroutine 中的恐慌?或者我应该完全避免使用close?


我不是在寻找替代方法(例如闭包)来实现同样的事情,只是想更好地了解渠道。


慕尼黑的夜晚无繁华
浏览 202回答 2
2回答

慕容3067478

Close是 goroutine 发送到通道以通知接收方您已完成此通道的好方法。另一种方式(你的问题)恕我直言是不可撤销的,至少是直接的。您可以添加一个完成的其他通道,它向您的斐波那契生成 goroutine 发出任务结束的信号。

白板的微信

这是您的示例的修改版本,它以允许(尽管不一定明智)的方式使用通道:package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "time")func fib(c chan int) {&nbsp; &nbsp; c <- 0&nbsp; &nbsp; c <- 1&nbsp; &nbsp; n, m := 0, 1&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; temp := n + m&nbsp; &nbsp; &nbsp; &nbsp; n = m&nbsp; &nbsp; &nbsp; &nbsp; m = temp&nbsp; &nbsp; &nbsp; &nbsp; c <- m&nbsp; &nbsp; &nbsp; &nbsp; if m > 100000000 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; close(c)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}func main() {&nbsp; &nbsp; start := time.Now()&nbsp; &nbsp; lastFib, newFib := 0, 0&nbsp; &nbsp; ok := true&nbsp; &nbsp; c := make(chan int)&nbsp; &nbsp; go fib(c)&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; newFib, ok = <-c&nbsp; &nbsp; &nbsp; &nbsp; if !ok {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(lastFib)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; lastFib = newFib&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Println(time.Now().Sub(start))}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go