6.3.2 recover
recover() 함수는 패니킹 작업으로부터 프로그램의 제어권을 다시 얻어 종료 절차를 중지시키고 프로그램을 계속 이어갈 수 있게 한다.
recover()는 반드시 defer 안에서 사용해야 한다. defer 구문 안에서 recover()를 호출하면 패닉 내부의 상황을 error 값으로 복원할 수 있다. recover()로 패닉을 복원한 후에는 패니킹 상황이 종료되고 함수 반환 타입의 제로값이 반환된다.
func main() { fmt.Println("result: ", divide(1, 0)) } func divide(a, b int) int { defer func() { if err := recover(); err != nil { fmt.Println(err) } }() return a / b }
실행 결과
runtime error: integer divide by zero
result: 0
이는 자바나 .Net의 try-catch 블록과 유사하다.
다음 protect() 함수는 매개변수로 받은 함수 g를 호출한다. 만약 g에서 패닉이 발생하면 패닉에서 error 정보를 가져와 출력한다.
func protect(g func()) { defer func() { log.Println("done") if err := recover(); err != nil { log.Printf("run time panic: %v", err) } }() log.Println("start") g() } func main() { protect(func() { fmt.Println(divide(4, 0)) }) } func divide(a, b int) int { return a / b }
실행 결과
start
done
run time panic: runtime error: integer divide by zero
이처럼 protect() 함수에 코드 블록을 클로저로 만들어 넘기면 예상치 못한 패닉에 의해 프로그램이 비정상적으로 종료되는 것을 막을 수 있다.