本文已参与「新人创作礼」活动,一起开启掘金创作之路。
在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
\