defer的执行顺序
多个defer是一个栈
的结构,是先进后出,下面这个代码的输出顺序是CBA。
package main
import "fmt"
func main() {
defer func1()
defer func2()
defer func3()
}
func func1() {
fmt.Println("A")
}
func func2() {
fmt.Println("B")
}
func func3() {
fmt.Println("C")
}
defer和return的顺序
先执行return,再执行defer。
package main
import "fmt"
func deferFunc() {
fmt.Println("defer func called")
}
func returnFunc() int {
fmt.Println("return func called")
return 0
}
func returnAndDefer() int {
defer deferFunc()
return returnFunc()
}
func main() {
returnAndDefer()
}
// output:
// return func called
// defer func called
函数命名返回值遇见defer
package main
import "fmt"
func foo() (t int) {
defer func() {
t = t * 10
}()
return 1
}
func main() {
fmt.Println(foo())
}
// output: 10
defer和panic
panic阻断defer
import (
"fmt"
)
func deferFn() {
defer func() { fmt.Println("defer before panic 1") }()
defer func() { fmt.Println("defer before panic 2") }()
panic("exit")
defer func() { fmt.Println("defer after panic") }()
}
func main() {
deferFn()
fmt.Println("main exit")
}
/*
output:
defer before panic 2
defer before panic 1
panic: exit
...
*/
defer里面的recover
defer在panic 后依然有效
package main
import (
"fmt"
)
func deferFn() {
defer func() {
fmt.Println("defer before panic 1")
if err := recover(); err != nil {
fmt.Println(err)
}
}()
defer func() { fmt.Println("defer before panic 2") }()
panic("panic info")
defer func() { fmt.Println("defer after panic") }()
}
func main() {
deferFn()
fmt.Println("main exit")
}
/*
output:
defer before panic 2
defer before panic 1
panic info
main exit
*/
defer中包含panic
panic仅有最后一个可以被revover捕获
package main
import (
"fmt"
)
func main() {
defer func() {
if err := recover(); err != nil {
fmt.Println(err)
} else {
fmt.Println("defer call")
}
}()
defer func() {
panic("defer panic")
}()
panic("main panic")
}
// output: defer panic
defer中函数有参数和包含子函数
package main
import "fmt"
func foo(index int, value int) int {
fmt.Println(index)
return index
}
func main() {
defer foo(1, foo(3, 0))
defer foo(2, foo(4, 0))
}
// output: 3 4 2 1
测试练习
package main
import "fmt"
func DeferFunc1(i int) (t int) {
t = i
defer func() {
t += 3
}()
return t
}
func DeferFunc2(i int) int {
t := i
defer func() {
t += 3
}()
return t
}
func DeferFunc3(i int) (t int) {
defer func() {
t += i
}()
return 2
}
func DeferFunc4() (t int) {
defer func(i int) {
fmt.Println(i)
fmt.Println(t)
}(t)
t = 1
return 2
}
func main() {
fmt.Println(DeferFunc1(1))
fmt.Println(DeferFunc2(1))
fmt.Println(DeferFunc3(1))
DeferFunc4()
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。