在 Go 中,传递参数的匿名函数的行为可能与闭包不同。本文深入探讨了区别及其含义。
闭包示例:
func main() { done := make(chan bool, 1) go func() { time.Sleep(50 * time.Millisecond) done <- true }() <-done }
在此闭包中,匿名函数没有参数,而是访问周围范围中存在的完成通道。
参数示例:
func main() { done := make(chan bool, 1) go func(c chan bool) { time.Sleep(50 * time.Millisecond) c <- true }(done) <-done }
在这种情况下,匿名函数接受一个参数 c,它是一个通道,并直接与其交互。
何时使用参数
将参数传递给匿名函数主要在共享变量可能导致意外行为的情况下有用。考虑以下示例:
for i := 0; i < 3; i++ { go func() { fmt.Println(i) }() // Closure }
这里,匿名函数是一个闭包,即它引用 for 循环中定义的 i 变量。由于所有 goroutine 共享相同的 i 变量,因此它们将打印“3”(循环完成后 i 的最终值),即使我们可能期望它们打印“0”、“1”和“2”。
为了纠正这个问题,我们可以将 i 作为参数传递:
for i := 0; i < 3; i++ { go func(v int) { fmt.Println(v) }(i) // Parameter }
现在,每个 goroutine 在调用函数时都会收到 i 变量的副本,从而产生正确的输出:" 0”、“1”和“2”。
结论
虽然闭包允许方便地访问周围范围内的变量,但传递参数提供了更多的控制和确保处理共享变量时的可预测行为,特别是在并发场景中。
以上是何时在 Go 匿名函数中使用参数与闭包?的详细内容。更多信息请关注PHP中文网其他相关文章!