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
吗?
我不是在寻找替代方法(例如闭包)来实现同样的目的,只是想更好地理解频道。
答案 0 :(得分:7)
Close
是goroutine发送到频道的好方法,用于通知接收方您已完成此频道。反过来(你的问题)是IMHO可撤销,至少是直接的。你可以添加一个其他通道来完成你的fibonacci生成goroutine的任务结束。
答案 1 :(得分:1)
以下是您的示例的修改版本,该版本以允许(但不一定是明智的)方式使用频道:
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))
}