Go面试题29
1: 下面这段代码是否正常结束?
func main() {
v := []int{1,2,3}
for i := range v {
v = append(v, i)
}
}
2: 下面这段代码输出什么? 为什么?
func main() {
var m = [...]int{1,2,3}
for i, v := range m {
go func(){
fmt.Println(i, v)
}()
}
time.Sleep(time.Second * 3)
}
参考答案及解析
1: 答案及解析: 不会出现死循环, 能正常结束. 循环次数在循环开始前就已经确定, 循环内改变切片的长度,不影响循环次数.
2: 答案及解析:
2 3
2 3
2 3
for range
使用短变量声明(:=)
的形式迭代变量, 需要注意的是,变量i, v
在每次循环体中都会被重用, 而不是重新声明.
各个groutine
中输出的i,v
值都是for range
循环结束后的i,v
最终值, 而不是各个goroutine
启动时的i,v
的值.可以理解为闭包引用,使用的是上下文环境的值.
两种可行的解决方法:
1: 使用函数传递:
for i, v := range m {
go func(i, v int) {
fmt.Println(i, v)
}(i, v)
}
2: 使用临时变量保留当前值
for i, v := range m {
i := i // 这里的:= 会重新声明变量,而不是重用
v := v
go func() {
fmt.Println(i, v)
}()
}
「真诚赞赏,手留余香」
真诚赞赏,手留余香
使用微信扫描二维码完成支付