-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
第 33 期 Go defer 和逃逸分析 #199
Comments
有理有据 有套路 很不错 |
defer4.go执行输出顺序是e1,e2,e3而不是e3,e2,e1。因为e1,e2,e3函数最后不管有没有return,编译器都会生成deferreturn()函数。这个deferreturn()里面就会执行jmpdefer从而执行deferd函数。而不是都压栈了统一执行。 |
你是对的,谢谢指正! 附上源码: /*
1. 参数在defer注册的时候就会求值
2. 闭包引用的外部变量,使用的是err最后的值
*/
package main
import (
"fmt"
"errors"
)
func e1() {
var err error
defer fmt.Println(err, ": e1")
err = errors.New("defer1 error")
return
}
func e2() {
var err error
defer func() {
fmt.Println(err)
}()
err = errors.New("defer2 error")
return
}
func e3() {
var err error
defer func(err error) {
fmt.Println(err, ": e3")
}(err)
err = errors.New("defer3 error")
return
}
func main() {
e1()
e2()
e3()
} 输出: <nil> : e1
defer2 error
<nil> : e3 |
defer6.go 中你本来的代码大概是这样的: func main() {
defer fmt.Println("defer main")
var user = ""
go func(){
defer func() {
fmt.Println("defer caller")
if err := recover();err!=nil {
fmt.Println("recover success. err:", err)
}
}()
func(){
defer func() {
fmt.Println("defer here")
}()
if user == "" {
panic("should set user env")
}
// 剩下的不要了,没得什么用
}()
}()
time.Sleep(time.Second) //时间我改了下
fmt.Println("end of main function")
} 然后我把这个代码改成这样: func main() {
defer fmt.Println("defer main")
var user = ""
go func(){
defer func() { // 这里增加了一层,
func() {
fmt.Println("defer caller")
if err := recover();err!=nil {然后这个recover就不能捕获到下面的那个panic了
fmt.Println("recover success. err:", err)
}
}()
}()
func(){
defer func() {
fmt.Println("defer here")
}()
if user == "" {
panic("should set user env")
}
}()
}()
time.Sleep(time.Second)
fmt.Println("end of main function")
} 然后,就不能捕获到panic了,这个东西怎么理解呀。原理是怎样的,能讲解下么。 |
func main() {
defer fmt.Println("defer main")
var user = ""
go func(){
defer recover()
func(){
defer func() {
fmt.Println("defer here")
}()
if user == "" {
panic("should set user env")
}
}()
}()
time.Sleep(time.Second)
fmt.Println("end of main function")
} 这样也是捕获不了的 |
defer func() {
fmt.Println("defer caller")
if err := recover();err!=nil {
fmt.Println("recover success. err:", err)
}
}() 规定是这样,才能捕获。 |
https://reading.developerlearning.cn/reading/33-2019-03-07-defer-in-go/
Night Reading Go - Go source reading and offline technical discussion every Thursday night.
The text was updated successfully, but these errors were encountered: