概念
闭包包含了函数的入口地址和其关联的环境
闭包和普通函数
最大的区别在于,闭包函数中可以引用闭包外的变量
闭包与range
当闭包和range同时使用,可能会出现下面的错误,最终协程会打印出values切片的最后一个值,因为当前的val值引用的是同一个地址的数据,在range循环的过程中,会不断的在val地址中更新数据,但是在闭包中,由于引用了外部的变量val,所以在访问时会获取val地址中的值,可能会获取最后放入其中的值,而不是遍历所有值,从而导致错误
import (
"fmt"
"time"
)
func main() {
links := []string{"https://www.baidu.com",
"https://www.jd.com/",
"https://www.taobao.com"}
for _, val := range links {
go func() {
fmt.Println(val)
}()
}
time.Sleep(2 * time.Second)
}
运行结果
https://www.taobao.com
https://www.taobao.com
https://www.taobao.com
修复
修复该问题的办法是通过函数传递参数
package main
import (
"fmt"
"time"
)
func main() {
links := []string{"https://www.baidu.com",
"https://www.jd.com/",
"https://www.taobao.com"}
for _, val := range links {
go func(val string) {
fmt.Println(val)
}(val)
}
time.Sleep(2 * time.Second)
}
运行结果
https://www.baidu.com
https://www.taobao.com
https://www.jd.com/