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()}