記事の内容は間違いがあり得ますので、ご了承いただけると幸いです。内容の間違い、認識の違い、違う意見などありましたら、コメント大歓迎です!
defer
deferとして定義した構文や関数をStackに保持しておき、現在の関数処理の終了とともにPOPされて実行する
Example
package main
import "fmt"
func main() {
fmt.Println("Main func start") // 1
defer func() { fmt.Println("First defer") }() // 4
defer func() { fmt.Println("Second defer") }() // 3
fmt.Println("Main func end") // 2
}
Result
Main func start
Main func end
Second defer
First defer
panic
現在の関数処理を止めて、Stackに登録されているdefer関数をPopし実行する
Example
package main
import "fmt"
func main() {
fmt.Println("Main func start") // 1
defer func() { fmt.Println("Main func first defer ") }() // 6
foo()
defer func() { fmt.Println("Main func second defer") }()
fmt.Println("Main func end")
}
func foo() {
fmt.Println("Foo func start") // 2
defer func() { fmt.Println("Foo func first defer ") }() // 5
bar()
defer func() { fmt.Println("Foo func second defer") }()
fmt.Println("Foo func end")
}
func bar() {
fmt.Println("Bar func start") // 3
defer func() { fmt.Println("Bar func first defer ") }() // 4
panic("Ops..")
defer func() { fmt.Println("Bar func second defer") }()
fmt.Println("Bar func end")
}
Result
Main func start
Foo func start
Bar func start
Bar func first defer
Foo func first defer
Main func first defer
panic: Ops..
goroutine 1 [running]:
main.bar()
D:/repository/go-testcode/main.go:28 +0xbe
main.foo()
D:/repository/go-testcode/main.go:19 +0xa3
main.main()
D:/repository/go-testcode/main.go:9 +0xa3
recover
- panic状態を正常状態に戻す
- defer関数ないで利用するのが一般的
- panic発生の関数の処理は止められるが、panic発生関数の上位関数の処理は継続される
Example
package main
import "fmt"
func main() {
fmt.Println("Main func start") // 1
defer func() { fmt.Println("Main func first defer ") }() // 10
foo()
defer func() { fmt.Println("Main func second defer") }() // 9
fmt.Println("Main func end") // 8
}
func foo() {
fmt.Println("Foo func start") // 2
defer func() { fmt.Println("Foo func first defer ") }() // 7
bar()
defer func() { fmt.Println("Foo func second defer") }() // 6
fmt.Println("Foo func end") // 5
}
func bar() {
fmt.Println("Bar func start") // 3
defer func() {
fmt.Println("Bar func first defer ") // 4
recover()
}()
panic("Ops..") // 함수를 종료
defer func() { fmt.Println("Bar func second defer") }()
fmt.Println("Bar func end")
}
Result
Main func start
Foo func start
Bar func start
Bar func first defer
Foo func end
Foo func second defer
Foo func first defer
Main func end
Main func second defer
Main func first defer