go defer 有参和无参问题
遇到defer一个陷阱:

打印结果:

为什么,两次defer 值不一样?
defer 函数的入参在defer的时候已经确定了,
所以第一个defer,入参值拷贝
第二个defer无参数,但是defer函数捕获外部变量形成闭包,即funcval和外部参数逃逸到堆上
在golang中,defer是在函数结束时调用,但是defer 函数参数确是立即求值的。请看如下代码:
package main
import "fmt"
func world() string {
fmt.Println("1.world is running")
return "world"
}
func hello(){
defer func(s string){
fmt.Println("3.hello is in defer:", s)
}(world()) //这里world会立即求值
fmt.Println("2.hello is running")
}
func main(){
hello()
}
go run defer.go
1.world is running
2.hello is running
3.hello is in defer: world
参数求值顺序也是自然的从左向右啦
package main
import "fmt"
func world() string {
fmt.Println("1.world is running")
return "world"
}
func world2() string {
fmt.Println("2.world2 is running")
return "world2"
}
func hello(){
defer func(s string, s2 string){
fmt.Println("4.hello is in defer:", s, s2)
}(world(), world2())
fmt.Println("3.hello is running")
}
func main(){
hello()
}
go run defer.go
1.world is running
2.world2 is running
3.hello is running
4.hello is in defer: world world2
函数内装饰对局部变量是引用,所以defer里会受影响
package main
import "fmt"
func world() string {
fmt.Println("1.world is running")
return "world"
}
func world2(n int) string {
fmt.Println("2.world2 is running")
return fmt.Sprintf("world2.%d", n)
}
func hello(){
n := 10
defer func(s string, s2 string){
fmt.Println("4.hello is in defer:", s, s2)
}(world(), world2(n)) //此处n已经确定,n是拷贝确定
defer func(){
fmt.Println("inner defer:", n) //n是引用,会受到下面的影响
}()
n = 20 //此修改不影响第一个defer闭包里的n,但是影响第二个
fmt.Println("3.hello is running")
}
func main(){
hello()
}
go run defer.go
1.world is running
2.world2 is running
3.hello is running
inner defer: 20
4.hello is in defer: world world2.10
————————————————
版权声明:本文为CSDN博主「wyg_031113」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wyg_031113/article/details/106615771

浙公网安备 33010602011771号