知っているようで知らなかったGo言語のdefer
tl;dr
- ここを読みましょう
これどういう動作になるか分かりますか?
package main import "fmt" func trace(s string) string { fmt.Println("entering: ", s) return s } func un(s string) { fmt.Println("leaving: ", s) } func a() { defer un(trace("a")) fmt.Println("in a") } func b() { defer un(trace("b")) fmt.Println("in b") a() } func main() { b() }
分かりました?(私は間違えました...)
では、答えです。
C:\Windows\system32\cmd.exe /c ( go run main.go) entering: b in b entering: a in a leaving: a leaving: b
パッと見b()のprint文が最初に出力されそうですけど、そうではないんですね。
deferで指定されていても、内側のtrace("b")は実行されます。
ただし、un()はdefer指定されているので一番最後に実行されます。
ちなみに、deferの順番はLIFOです。(a -> bの順番)
まとめ
- deferの指定の仕方を間違えると思わぬバグとなりそうです。
- deferはLIFOです。
- 2年くらいGo言語使ってますけど、新しい発見があって楽しい。