GO语言延迟调用
关键字 defer ⽤用于注册延迟调⽤用。这些调⽤用直到 ret 前才被执⾏行,通常⽤用于释放资源或错
误处理。
func test() error {
f, err := os.Create("test.txt")
if err != nil { return err }
defer f.Close() // 注册调⽤用,⽽而不是注册函数。必须提供参数,哪怕为空。
f.WriteString("Hello, World!")
return nil
}
多个 defer 注册,按 FILO 次序执⾏行。哪怕函数或某个延迟调⽤用发⽣生错误,这些调⽤用依旧
会被执⾏行。
func test(x int) {
defer println("a")
defer println("b")
defer func() {
println(100 / x) // div0 异常未被捕获,逐步往外传递,最终终⽌止进程。
}()
defer println("c")
}
func main() {
test(0)
}
输出:
c
b
a
panic: runtime error: integer divide by zero
延迟调⽤用参数在注册时求值或复制,可⽤用指针或闭包 "延迟" 读取。
func test() {
x, y := 10, 20
defer func(i int) {
println("defer:", i, y) // y 闭包引⽤用
}(x) // x 被复制
x += 10
y += 100
println("x =", x, "y =", y)
}
输出:
x = 20 y = 120
defer: 10 120
滥⽤用 defer 可能会导致性能问题,尤其是在⼀一个 "⼤大循环" ⾥里。
var lock sync.Mutex
func test() {
lock.Lock()
lock.Unlock()
}
func testdefer() {
lock.Lock()
defer lock.Unlock()
}
func BenchmarkTest(b *testing.B) {
for i := 0; i < b.N; i++ {
test()
}
}
func BenchmarkTestDefer(b *testing.B) {
for i := 0; i < b.N; i++ {
testdefer()
}
}
输出:
BenchmarkTest" 50000000 43 ns/op
BenchmarkTestDefer 20000000 128 ns/op