2026년 상식닷컴 선정 식당 & 카페 리스트
최근에 오픈한 호텔을 찾는다면 살펴보세요

Go 언어의 `defer` 문을 사용할 때 주의할 점은 무엇인가요?

_____
Q1: `defer` 문은 언제 실행되나요?
`defer`로 지정한 함수 호출은 해당 함수가 종료되기 직전에 실행됩니다. 즉, 현재 함수의 모든 작업이 끝나고 반환하기 바로 전에 실행됩니다.

---

Q2: `defer` 호출 시 인자는 언제 평가되나요?
`defer` 함수의 인자는 `defer` 문이 실행되는 시점에 즉시 평가됩니다. 단, 함수 호출은 나중에 함수 종료 직전에 실행됩니다.

---

Q3: 여러 개의 `defer` 문이 있을 때 실행 순서는?
`defer` 문은 스택처럼 동작하여 가장 최근에 등록된 `defer`가 먼저 실행됩니다. 즉, 후입선출(LIFO) 순서로 실행됩니다.

---

Q4: `defer` 사용 시 성능 문제는 없나요?
`defer`는 편리하지만 반복문 안에서 과도하게 사용하면 약간의 성능 저하가 발생할 수 있습니다. 반복문 내에서는 꼭 필요한 경우에만 사용하는 것이 좋습니다.

---
Q5: 패닉(panic)이 발생해도 `defer`는 실행되나요?
네, 패닉이 발생해도 해당 함수가 종료될 때 `defer`문으로 등록된 함수들은 실행됩니다. 단, 패닉이 recover되지 않으면 프로그램은 종료됩니다.

---

Q6: `defer` 안에서 반환값을 수정할 수 있나요?
이름 있는 반환값을 사용하면 `defer` 안에서 해당 변수 값을 변경하여 반환 값을 바꿀 수 있습니다. 하지만 일반 반환 변수일 경우에는 바꾸지 못합니다.

---

Q7: `defer`는 언제 사용하면 좋나요?
리소스 해제, 파일 닫기, 락 해제 등 함수 종료 시 반드시 실행되어야 할 코드를 작성할 때 사용하면 코드가 깔끔하고 안전해집니다.

---

Q8: `defer` 함수가 다른 `defer`를 호출할 수 있나요?
네, `defer` 안에서 또 다른 `defer`를 등록할 수 있으나, 이 경우에도 호출 순서는 후입선출 방식으로 적용됩니다.

---

이상으로 Go 언어 `defer`를 사용할 때 가장 빈번히 주의해야 할 점들을 정리했습니다.
Go 언어에서 `defer` 문은 함가 종료될 때 호출할 함수를 예약하는 데 사용됩니다.

`defer`는 주로 리소스 해제, 파일 닫기, 뮤텍스 잠금 해제 등과 같은 작업을 안전하게 수행하기 위해 사용됩니다.

그러나 `defer`를 사용할 때 주의해야 할 몇 가지 중요한 점이 있습니다.

1. 실행 순서 `defer` 문은 LIFO(Last In, First Out) 방식으로 실행됩니다.

즉, 여러 개의 `defer` 문이 있을 경우, 가장 나중에 호출된 `defer` 문이 가장 먼저 실행됩니다.

이 점은 여러 개의 `defer` 문을 사용할 때 예상치 못한 결과를 초래할 수 있으므로 주의해야 합니다.

```go func example() { defer fmt.Println("첫 번째 defer") defer fmt.Println("두 번째 defer") fmt.Println("함수 실행 중") } // 출력: // 함수 실행 중 // 두 번째 defer // 첫 번째 defer ```

2. 성능 `defer` 문은 함수 호출 시점에 약간의 성능 오버헤드를 발생시킵니다.

특히, 반복문 안에서 `defer`를 사용하면 성능 저하가 발생할 수 있습니다.

반복문이 여러 번 실행될 경우, 각 반복마다 `defer`가 호출되므로 성능에 영향을 줄 수 있습니다.

이 경우, `defer` 대신 직접 호출하는 것이 더 효율적일 수 있습니다.

```go for i := 0; i < 1000; i++ { defer fmt.Println(i) // 성능 저하 } ```

3. 인자 평가 `defer` 문에서 호출되는 함수의 인자는 `defer` 문이 실행될 때가 아니라, `defer` 문이 선언될 때 평가됩니다.

이는 `defer` 문이 호출될 때의 상태가 아닌, 선언 시점의 상태를 반영한다는 것을 의미합니다.

```go func example() { for i := 0; i < 3; i++ { defer fmt.Println(i) // i의 값이 아닌, i의 현재 상태가 평가됨 } } // 출력: // 2 // 1 // 0 ```

4. 패닉 처리 `defer` 문은 패닉을 처리하는 데 유용합니다.

`defer`를 사용하여 패닉 발생 시 리소스를 정리하거나 로그를 남길 수 있습니다.

`recover` 함수를 사용하여 패닉을 복구할 수 있습니다.

```go func safeFunction() { defer func() { if r := recover(); r != nil { fmt.Println("패닉 발생:", r) } }() // 패닉을 발생시키는 코드 panic("문제가 발생했습니다!") } // 출력: // 패닉 발생: 문제 발생! ```

5. 가독성 `defer` 문은 코드의 가독성을 높이는 데 기여할 수 있습니다.

리소스 해제나 정리 작업을 함수의 끝에 배치함으로써, 코드의 흐름을 더 명확하게 이해할 수 있게 됩니다.

그러나 과도한 `defer` 사용은 오히려 가독성을 떨어뜨릴 수 있으므로 적절히 사용하는 것이 중요합니다.

결론 Go 언어의 `defer` 문은 매우 유용한 기능이지만, 그 사용에 있어 몇 가지 주의할 점이 있습니다.

실행 순서, 성능, 인자 평가, 패닉 처리 및 가독성 등을 고려하여 적절하게 사용해야 합니다.

이러한 점들을 염두에 두고 `defer`를 활용하면, 코드의 안정성과 가독성을 높일 수 있습니다.

작성자: 박하윤 [비회원] | 작성일자: 1년 전 2024-09-19 01:50:31
조회수: 141 | 댓글: 0 | 좋아요: 0 | 싫어요: 0
내용이 부정확하다면 싫어요를 클릭해주세요.