0%

go defer, panic, recover 정리

defer

문장이나 함수를 stack 에 쌓아두고 현재 함수 종료와 함께 pop 되어 실행하는 keyword 입니다.

1
2
3
4
5
6
7
8
9
10
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
}

결과

1
2
3
4
Main func start
Main func end
Second defer
First defer

panic

현재 함수를 멈추고 stack 에 등록된 defer 함수를 pop 하여 실행합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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")
}

결과

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 상태를 다시 정상으로 되돌립니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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")
}

결과

1
2
3
4
5
6
7
8
9
10
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