eddycjy / blog

煎鱼的博客,有点忙,传送门:https://eddycjy.com
3.05k stars 429 forks source link

posts/go/go-tips-defer/ #136

Open utterances-bot opened 3 years ago

utterances-bot commented 3 years ago

Go 群友提问:学习 defer 时很懵逼,这道不会做!

https://eddycjy.com/posts/go/go-tips-defer/

treachery commented 3 years ago

func f() (r int) { fmt.Printf("func: r=%d,%p\n",r,&r) t := 5

defer func() { t = t + 5 fmt.Printf("defer: t=%d,%p\n",t,&t) }()

return func(t int)int{ r = t fmt.Printf("return: t=%d,%p, r=%d,%p\n",t,&t,r,&r) return r }(t) }

func main() { println(f()) }

执行结果: func: r=0,0xc00012e020 return: t=5,0xc00012e048, r=5,0xc00012e020 defer: t=10,0xc00012e040 5

可以看出执行顺序, func->return->defer

vissible commented 3 years ago

首先f1, f2, f3返回值都是r, f1返回值r和defer里r是同一作用域, f2的defer里变量是t, f3的defer是值传递

ngyhd commented 3 years ago

最后一题的理解: 1.执行顺序func->return->defer 2.func f2() (r int){... return t} 相当于把r赋值给t ->r = t 所以r = 5 3.值传递,非引用传递

miller-star commented 2 years ago

package main

import "fmt"

func main() { fmt.Println(f1()) fmt.Println(f2()) fmt.Println(f3()) } //r<-0 r++ ret func f1() (r int) { defer func() { r++ }() return 0 } //r<-t t<-t+5 ret func f2() (r int) { t := 5 defer func() { t = t + 5 }() return t } //r<-1 r拷贝出一个r1 r1<-r1+5 ret func f3() (r int) { defer func(r int) { r = r + 5 }(r) return 1 }