我喜欢@
tux21b的答案;在
fib()函数中创建通道可以使调用代码清晰美观。详细说明一下,如果在调用时无法告诉函数何时停止,则只需要一个单独的“退出”通道。如果您只关心“最多X个数字”,则可以执行以下操作:
package mainimport "fmt"func fib(n int) chan int { c := make(chan int) go func() { x, y := 0, 1 for x < n { c <- x x, y = y, x+y } close(c) }() return c}func main() { // Print the Fibonacci numbers less than 500 for i := range fib(500) { fmt.Println(i) }}如果您想要执行任何一项操作,这有点草率,但是我个人比较喜欢测试呼叫者中的条件,然后通过单独的通道发出退出信号:
func fib(wanted func (int, int) bool) chan int { c := make(chan int) go func() { x, y := 0, 1 for i := 0; wanted(i, x); i++{ c <- x x, y = y, x+y } close(c) }() return c}func main() { // Print the first 10 Fibonacci numbers for n := range fib(func(i, x int) bool { return i < 10 }) { fmt.Println(n) } // Print the Fibonacci numbers less than 500 for n := range fib(func(i, x int) bool { return x < 500 }) { fmt.Println(n) }}我认为这是否取决于给定情况的具体情况:
- 告诉生成器何时停止生成
- 传递显式数量的值以生成
- 传递目标值
- 传递确定是否继续运行的函数
- 给生成器一个“退出”通道,自己测试值,并在适当的时候告诉它退出。
总结并实际回答您的问题:
由于上下文切换较少,因此增加通道大小将有助于提高性能。在这个简单的示例中,性能和内存消耗都不会成为问题,但是在其他情况下,缓冲通道通常是一个很好的主意。
make (chan int, 100)
在大多数情况下,使用的内存似乎并不重要,但是很容易造成很大的性能差异。您的
fibonacci
函数中有一个无限循环,因此运行它的goroutine将永远运行(c <- x
在本例中为on )。您(一旦c
超出了调用者的范围)就不会再从与之共享的频道中读取该事实并不会改变这一点。正如@ tux21b所指出的,该通道将永远不会被垃圾回收,因为它仍在使用中。这与关闭通道无关(其目的是让通道的接收端知道不再有值了),并且与不从函数中返回无关。



