为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕尼黑的夜晚无繁华 2021-07-04 09:15:05
package mainimport (    "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?我不是在寻找替代方法(例如闭包)来实现同样的事情,只是想更好地了解渠道。
查看完整描述

2 回答

?
慕容3067478

TA贡献1773条经验 获得超3个赞

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


查看完整回答
反对 回复 2021-07-19
?
白板的微信

TA贡献1883条经验 获得超3个赞

这是您的示例的修改版本,它以允许(尽管不一定明智)的方式使用通道:


package main


import (

    "fmt"

    "time"

)


func fib(c chan int) {

    c <- 0

    c <- 1


    n, m := 0, 1

    for {

        temp := n + m

        n = m

        m = temp

        c <- m

        if m > 100000000 {

            close(c)

            break

        }

    }

}


func main() {

    start := time.Now()

    lastFib, newFib := 0, 0

    ok := true

    c := make(chan int)

    go fib(c)


    for {

        newFib, ok = <-c

        if !ok {

            fmt.Println(lastFib)

            break

        }

        lastFib = newFib

    }


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

}



查看完整回答
反对 回复 2021-07-19
  • 2 回答
  • 0 关注
  • 201 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信