일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- EC2
- 피로그래밍
- 알고리즘
- BFS
- 코딩테스트
- AWS
- 배포
- Baekjoon
- Database
- GROUPBY
- 그래프 탐색
- 크루스칼
- SQL코딩테스트
- Pirogramming
- 프림
- Java
- JOIN
- 누적합
- django
- union find
- 자바
- 백준
- OrderBy
- 최단경로
- MST
- 다익스트라
- 프로그래머스
- 구현
- db
- SQL
Archives
- Today
- Total
NullNull
Go lang : defer 키워드 본문
defer
- 함수나 코드의 실행을 가장 마지막까지 미룰 수 있음
- defer 키워드가 있는 함수나 코드는 실행이 바로 되지 않고 그 함수의 실행이 끝난 후 LIFO 방식으로 실행됨
package main
import "fmt"
func d1() {
fmt.Println("d1 function")
for i := 3; i > 0; i-- {
defer fmt.Print(i, " ")
}
}
func d2() {
fmt.Println("d2 function")
for i := 3; i > 0; i-- {
defer func() {
fmt.Print(i, " ")
}()
}
}
func d3() {
fmt.Println("d3 function")
for i := 3; i > 0; i-- {
defer func(n int) {
fmt.Print(n, " ")
}(i)
}
}
func main() {
d1()
fmt.Println()
d2()
fmt.Println()
d3()
fmt.Println()
}
d1 함수
3부터 1까지 실행하면서 i를 출력한다. 이때 출력하는 코드 앞에 defer을 적었기 때문에, 해당 코드는 d1함수가 종료될 때 실행된다. defer 키워드를 만나 가장 최근에 실행을 미루었던 코드부터 실행된다.
만나는 순서
- defer fmt.Print(3, " ")
- defer fmt.Print(2, " ")
- defer fmt.Print(1, " ")
위의 순서대로 함수를 만나기 때문에 실행될 때는 가장 최근에 실행이 미루어진 fmt.Print(1, “ ”) 가 실행된다.
실행 순서
- fmt.Print(1, " ")
- fmt.Print(2, " ")
- fmt.Print(3, " ")
실행 결과
d1 function
1 2 3
d2 함수
d1 함수와 실행이 비슷하다. 하지만 이 경우에는 익명 함수 앞에 defer 키워드를 적었으므로 익명 함수의 실행이 미루어진다. 함수의 실행 순서를 세분화 하면 다음과 같다.
실행 순서
- d2 function을 출력한다.
- for문에 들어간다.
- i가 3이다. 이때 defer 함수 뒤의 익명함수는 실행이 미루어진다.
- i가 2이다. 이때 defer 함수 뒤의 익명함수는 실행이 미루어진다.
- i가 1이다. 이때 defer 함수 뒤의 익명함수는 실행이 미루어진다.
- for문을 벗어난다.
- 이제 미루었던 함수를 실행한다.
- i가 1일때 미루어졌던 익명함수를 실행한다. i값을 출력해야 한다. for문이 끝남과 동시에 i에는 0이 할당되어 있다. (i가 1인 상황에서 i— 연산을 통해 0으로 바뀐 뒤 for문을 벗어났기 때문이다.) for 문이 끝나서 i에 더이상 1이 할당되어있지 않다. 이에 0을 출력한다.
- i가 2일때 미루어졌던 익명함수를 실행한다. i값을 출력해야 한다. for문이 끝남과 동시에 i에는 0이 할당되어 있다. (i가 1인 상황에서 i— 연산을 통해 0으로 바뀐 뒤 for문을 벗어났기 때문이다.) for 문이 끝나서 i에 더이상 2이 할당되어있지 않다. 이에 0을 출력한다.
- i가 3일때 미루어졌던 익명함수를 실행한다. i값을 출력해야 한다. for문이 끝남과 동시에 i에는 0이 할당되어 있다. (i가 1인 상황에서 i— 연산을 통해 0으로 바뀐 뒤 for문을 벗어났기 때문이다.) for 문이 끝나서 i에 더이상 3이 할당되어있지 않다. 이에 0을 출력한다.
실행 결과
d2 function
0 0 0
실행이 미루어진 익명 함수가 for 루프가 끝난 뒤에 평가받는다. 이 함수는 매개변수를 받지 않기 때문에 i가 0인 상태에서 3번 출력된 것 이다.
d3 함수
d2 함수와 실행이 비슷하다. 하지만 이 경우에는 익명 함수에게 별도의 매개변수를 전달한다. 함수의 실행 순서를 세분화 하면 다음과 같다.
실행 순서
- d3 function을 출력한다.
- for문에 들어간다.
- i가 3이다. 이때 defer 함수 뒤의 익명함수는 매개변수 3과 함께 실행이 미루어진다.
- i가 2이다. 이때 defer 함수 뒤의 익명함수는 매개변수 2와 함께 실행이 미루어진다.
- i가 1이다. 이때 defer 함수 뒤의 익명함수는 매개변수 1과 함께 실행이 미루어진다.
- for문을 벗어난다.
- 이제 미루었던 함수를 실행한다.
- i가 1일때 미루어졌던 익명함수를 실행한다. n값을 출력해야 한다. 미루어졌을 당시의 n값 1을 기억하고 있으므로 1을 출력한다.
- i가 2일때 미루어졌던 익명함수를 실행한다. n값을 출력해야 한다. 미루어졌을 당시의 n값 2을 기억하고 있으므로 2을 출력한다.
- i가 3일때 미루어졌던 익명함수를 실행한다. n값을 출력해야 한다. 미루어졌을 당시의 n값 3을 기억하고 있으므로 3을 출력한다.
실행 결과
d3 function
1 2 3
매개변수를 받기 때문에, 매번 실행이 미루어질 때마다 현재 상태의 i 값을 가져와서 사용한다. 따라서 익명 함수가 실행될 때마다 처리할 값이 달라져서 다음과 같은 결과가 나온다.
💡 가장 바람직한 defer 사용 방법은 d3일 것이다. 원하는 변수를 명시적으로 익명 함수에 전달해 이해하기 쉽기 때문이다.
'프로그래밍 언어 > GO' 카테고리의 다른 글
Go routine이 무엇일까? (0) | 2022.10.23 |
---|
Comments