PHpullh
학습 라이브러리/Go/defer & panic & recover

GO · 함수

defer & panic & recover

defer로 리소스를 안전하게 해제하고, recover로 패닉을 복구합니다.

함수중급deferpanicrecoverLIFO리소스해제

핵심 설명

defer로 리소스를 안전하게 해제하고, recover로 패닉을 복구합니다.

Go code

package main

import "fmt"

// defer — 함수 종료 시 실행 (LIFO 순서)
func readFile(name string) {
	fmt.Println("파일 열기:", name)
	defer fmt.Println("파일 닫기:", name) // 나중에 실행

	fmt.Println("파일 읽기")
	// 어떤 경로로 반환되어도 defer는 실행됨
}

// 여러 defer — LIFO (스택) 순서
func multiDefer() {
	for i := 0; i < 3; i++ {
		i := i // 루프 변수 캡처
		defer fmt.Println("defer:", i)
	}
	fmt.Println("함수 실행")
}

// panic & recover
func safeDivide(a, b int) (result int, err error) {
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Errorf("패닉 복구: %v", r)
		}
	}()

	result = a / b // b==0이면 패닉
	return
}

// 실용적 패턴 — 뮤텍스 해제
func processWithLock() {
	// mu.Lock()
	defer fmt.Println("Lock 해제") // mu.Unlock()
	fmt.Println("임계 구역 실행")
}

func main() {
	readFile("data.txt")

	fmt.Println("--- multiDefer ---")
	multiDefer() // 함수실행, defer:2, defer:1, defer:0

	fmt.Println("--- safeDivide ---")
	r, err := safeDivide(10, 2)
	fmt.Printf("10/2 = %d, err = %v
", r, err)

	r, err = safeDivide(10, 0)
	fmt.Printf("10/0 = %d, err = %v
", r, err)

	processWithLock()
}

학습 팁

defer는 등록 시점의 인자값을 캡처합니다. 루프 내 defer 변수는 클로저 문제가 생길 수 있으니 i := i로 새 변수를 만드세요.

주의할 점

recover()defer 함수 내부에서만 동작합니다. 일반 함수에서 호출하면 nil을 반환합니다.

자주 묻는 질문

defer & panic & recover란 무엇인가요?

defer 로 리소스를 안전하게 해제하고, recover 로 패닉을 복구합니다.

defer & panic & recover 학습 시 주의할 점은 무엇인가요?

recover() 는 defer 함수 내부에서만 동작합니다. 일반 함수에서 호출하면 nil을 반환합니다.