0
0

More than 1 year has passed since last update.

[Go] defer, panic, recover 簡単整理 (備忘録)

Posted at

記事の内容は間違いがあり得ますので、ご了承いただけると幸いです。内容の間違い、認識の違い、違う意見などありましたら、コメント大歓迎です!

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
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0