🔥 defer

480자
6분

Go 언어에서 defer 키워드는 함수 실행을 지연시키는 역할을 해요. defer 키워드를 사용하면 현재 함수가 끝날 때까지 해당 함수의 실행을 미룰 수 있답니다.

defer 키워드를 사용할 때는 지연시킬 함수 호출 앞에 defer를 붙이면 돼요. 이렇게 하면 현재 함수가 종료되기 직전에 지연된 함수가 실행된답니다.

package main
 
import "fmt"
 
func main() {
	defer fmt.Println("world") // 이 줄은 main 함수가 끝나기 직전에 실행돼요.
 
	fmt.Println("hello") // 이 줄은 먼저 실행되고, 그 다음에 위의 defer 문이 실행된답니다.
}
 
go

위의 예제 코드를 실행하면 다음과 같은 출력 결과를 볼 수 있어요:

hello
world
text

defer 키워드를 사용할 때는 두 가지 시점을 구분해서 이해해야 해요.

  1. 평가 시점 (Evaluation Time):
    • defer 문이 실행되는 시점을 의미해요.
    • defer 문에 전달된 인자의 값이 평가되는 시점이에요.
    • 평가된 값은 defer 문이 실행되는 시점의 값으로 고정돼요.
  2. 실행 시점 (Execution Time):
    • defer로 지연된 함수가 실제로 호출되는 시점을 의미해요.
    • 현재 함수가 종료되기 직전에 defer로 지연된 함수가 호출돼요.
    • 이때는 이미 평가 시점에서 고정된 인자 값이 사용돼요.
package main
 
import "fmt"
 
func main() {
	i := 1
	defer fmt.Println(i) // 평가 시점: i의 값은 1로 평가되고 고정돼요.
 
	i = 2 // i의 값을 2로 변경했지만, defer 문에서는 영향을 받지 않아요.
	fmt.Println(i) // 실행 시점: i의 값 2가 출력돼요.
} // 함수가 종료되기 직전, 지연된 defer 문이 실행돼요. 고정된 값 1이 출력돼요.
 
go

위의 예제 코드에서:

  • defer fmt.Println(i)가 평가되는 시점에 i의 값은 1로 평가되고 고정돼요.
  • i의 값을 2로 변경했지만, defer 문에는 영향을 주지 않아요.
  • fmt.Println(i)가 실행되면 현재 i의 값인 2가 출력돼요.
  • 함수가 종료되기 직전, 지연된 defer 문이 실행되면서 고정된 값 1이 출력돼요.

따라서 출력 결과는 다음과 같아요:

2
1
text

defer 키워드는 주로 파일을 닫거나, 잠금을 해제하거나, 자원을 해제하는 등의 클린업 작업을 수행할 때 유용하게 사용할 수 있어요. 함수가 여러 개의 반환 지점을 가질 때도 defer를 사용하면 중복 코드를 줄일 수 있죠.

package main
 
import "fmt"
 
func openFile() {
	// 파일을 열고 작업을 수행하는 코드
	fmt.Println("파일을 열었어요.")
 
	defer fmt.Println("파일을 닫았어요.") // openFile 함수가 종료되기 직전에 파일을 닫는 코드를 실행해요.
 
	// 파일 작업을 수행하는 코드
	fmt.Println("파일에서 데이터를 읽는 중이에요.")
}
 
func main() {
	openFile()
}
 
go

위의 예제 코드를 실행하면 다음과 같은 출력 결과를 볼 수 있어요:

파일을 열었어요.
파일에서 데이터를 읽는 중이에요.
파일을 닫았어요.
text

이렇게 defer 키워드를 사용하면 함수가 종료되기 직전에 파일을 닫는 작업을 수행할 수 있답니다. 파일을 열고 닫는 작업을 깜빡하지 않고 안전하게 처리할 수 있게 되죠.

defer 키워드를 사용할 때는 지연된 함수의 실행 순서에도 주의해야 해요. 만약 여러 개의 defer 문을 사용한다면, 가장 마지막에 호출된 defer 문부터 역순으로 실행된답니다.

package main
 
import "fmt"
 
func main() {
	defer fmt.Println("1")
	defer fmt.Println("2")
	defer fmt.Println("3")
}
 
go

위의 예제 코드를 실행하면 다음과 같은 출력 결과를 볼 수 있어요:

3
2
1
text

defer 키워드는 Go 언어에서 매우 강력하고 유용한 기능이에요. 함수 실행을 지연시켜 클린업 작업을 수행하거나, 자원을 안전하게 해제할 수 있게 해준답니다. 하지만 defer 키워드를 너무 남용하면 코드의 가독성과 성능에 악영향을 줄 수 있으니 적절히 사용하는 것이 중요해요.