defer, panic, recover使用总结
1. defer : 延迟调用。多个defer,依次入栈,在函数即将退出时,依次出栈调用
1 package main 2 import "fmt" 3 func main() { 4 defer func() { 5 fmt.Println("defer one") 6 }() 7 defer func() { 8 fmt.Println("defer two") 9 }() 10 defer func() { 11 fmt.Println("defer three") 12 }() 13 }
2. panic和defer结合使用:panic触发错误,defer依次出栈调用,没有recover捕获的情况下,最后才打印错误
1 package main 2 import "fmt" 3 func main() { 4 defer func() { 5 fmt.Println("defer one") 6 }() 7 defer func() { 8 fmt.Println("defer two") 9 }() 10 defer func() { 11 fmt.Println("defer three") 12 }() 13 panic("panic here") 14 }
3. defer,panic, recover 结合使用,panic触发错误,defer依次出栈调用,直到被recover捕获,打印捕获的信息,之后继续defer出栈
例一:
1 package main 2 import "fmt" 3 func main() { 4 defer func() { 5 fmt.Println("defer one") 6 }() 7 defer func() { 8 fmt.Println("defer two") 9 }() 10 defer func() { 11 if info := recover(); info != nil { 12 fmt.Println("catch: ", info) 13 } 14 fmt.Println("defer three") 15 }() 16 panic("panic here") 17 }
例二:
package main import "fmt" func main() { defer func() { fmt.Println("defer one") }() defer func() { if info := recover(); info != nil { fmt.Println("catch: ", info) } fmt.Println("defer two") }() defer func() { fmt.Println("defer three") }() panic("panic here") }
例三:
package main import "fmt" func main() { defer func() { if info := recover(); info != nil { fmt.Println("catch: ", info) } fmt.Println("defer one") }() defer func() { fmt.Println("defer two") }() defer func() { fmt.Println("defer three") }() panic("panic here") }
4. recover 必须在defer中调用,才有效,否则返回nil
package main import "fmt" func main() { if info := recover(); info != nil { fmt.Println("catch: ", info) } else { fmt.Println("recover return nil") } defer func() { fmt.Println("defer one") }() defer func() { fmt.Println("defer two") }() defer func() { fmt.Println("defer three") }() panic("panic here") }
5. panic 其后的代码不会执行
例一:
package main import "fmt" func main() { defer func() { fmt.Println("defer one") }() defer func() { fmt.Println("defer two") }() defer func() { fmt.Println("defer three") }() panic("panic here") if info := recover(); info != nil { fmt.Println("catch: ", info) } else { fmt.Println("recover return nil") } }
例二:
package main import "fmt" func main() { defer func() { fmt.Println("defer one") }() defer func() { if v := recover(); v != nil { fmt.Println("catch panic error: ", v) } fmt.Println("defer two") }() defer func() { fmt.Println("defer three") }() panic("panic here") fmt.Println("after panic") }