type Number int
func (n Number) Print() {
fmt.Println(n)
}
func Example() (n Number) {
n = 10
// 1
defer n.Print()
// 2
defer func() {
n.Print()
}()
n += 10
return
}
20
10
---
즉,
1번 로직 결과 값 : 10
2번 로직 결과 값 : 20
함수를 실행하며 defer를 만나면 그 때 바로 defer stack에 넣어준다. ( return을 만나면 수행하기 시작하는 별도의 stack ? https://www.sohamkamani.com/golang/defer/ )
값이 다른 이유는,
defer n.Print() --> 스택에 바로 당시 시점의 n.Print()이 들어가고( n = 10 ), 차례가 오면 pop 되며, 10출력 ...
defer func() { n.Print() }() --> 스택에 함수가 들어가고< func() { n.Print() }() >, 차례가 오면 pop이 되고, 함수를 수행하며 그 시점의 n 값을 가져오기 때문에 20 출력 ( return을 만나기 직전의 n 값 )
( 위 말을 그림으로 표현 해봤습니다. )
func Example() (n Number) {
n = 10
// 1
defer n.Print()
n += 10
// 2
defer n.Print()
// 3
defer func() {
n.Print()
}()
n += 50
// 4
defer n.Print()
// 5
defer func() {
n.Print()
}()
n += 10
return
}
결과값
80
70
80
20
10
---
즉,
1 : 10
2 : 20
3 : 80 (익명함수)
4 : 70
5 : 80 (익명함수)
예상대로 나온다.
결론 : defer 익명함수안에 코드를 넣으면 return 직전의 값들로 함수가 수행되고, 단순 코드만 넣으면 그 시점의 값들로 함수가 수행된다.