Go defer, panic, recover
Go에서 defer, panic, recover는 에러 처리 및 리소스 정리에 중요한 역할을 합니다. 이 세 가지를 이해하고 활용하면 더 견고하고 안정적인 코드를 작성할 수 있습니다.
defer
defer 키워드는 함수가 종료되기 직전에 실행할 코드를 지정하는 데 사용됩니다. 주로 리소스 해제, 파일 닫기, 뮤텍스 해제 등의 작업에 사용됩니다. defer 문은 선언된 순서의 역순으로 실행됩니다.
예제: defer 사용
package main
import (
"fmt"
"os"
)
func main() {
f, err := os.Open("example.txt")
if err != nil {
fmt.Println(err)
return
}
defer f.Close() // 함수가 끝나기 직전에 파일을 닫습니다.
// 파일 작업 수행
fmt.Println("File opened successfully")
}
위 예제에서 defer f.Close()는 함수가 종료될 때 파일을 닫습니다.
panic
panic 함수는 프로그램이 정상적으로 실행될 수 없는 상황에서 사용됩니다. panic이 호출되면 현재 함수의 실행이 중지되고, defer된 함수들이 실행된 후 프로그램이 종료됩니다.
예제: panic 사용
package main
import "fmt"
func main() {
fmt.Println("Start")
panic("Something went wrong!")
fmt.Println("End") // 이 코드는 실행되지 않습니다.
}
위 예제에서 panic("Something went wrong!")이 호출되면 프로그램은 패닉 상태가 되고 종료됩니다.
recover
recover 함수는 패닉 상태를 복구하여 프로그램이 계속 실행될 수 있도록 합니다. recover는 반드시 defer 함수 내에서 호출되어야 합니다.
예제: recover 사용
package main
import "fmt"
func main() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from panic:", r)
}
}()
fmt.Println("Start")
panic("Something went wrong!")
fmt.Println("End") // 이 코드는 실행되지 않습니다.
}
위 예제에서 defer 함수 내에서 recover를 호출하여 패닉 상태를 복구하고 프로그램이 계속 실행될 수 있게 합니다.
defer, panic, recover를 함께 사용한 예제
아래는 defer, panic, recover를 함께 사용하여 에러 처리를 수행하는 예제입니다.
package main
import "fmt"
func riskyOperation() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in riskyOperation:", r)
}
}()
fmt.Println("Performing risky operation")
panic("Something went wrong!")
fmt.Println("This will not be printed")
}
func main() {
fmt.Println("Start main")
riskyOperation()
fmt.Println("End main")
}
위 예제에서 riskyOperation 함수는 패닉을 발생시키지만, defer된 함수 내에서 recover를 호출하여 패닉을 복구합니다. 따라서 프로그램은 종료되지 않고 계속 실행됩니다.
실용적인 활용 예제
파일 처리와 같은 리소스 해제를 위한 defer와 에러 핸들링을 위한 panic과 recover의 실제 활용 예제를 살펴보겠습니다.
package main
import (
"fmt"
"os"
)
func readFile(fileName string) {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered from panic:", r)
}
}()
file, err := os.Open(fileName)
if err != nil {
panic(fmt.Sprintf("Failed to open file: %s", err))
}
defer file.Close()
// 파일 처리 로직 (예: 읽기)
fmt.Println("File opened successfully")
}
func main() {
readFile("example.txt")
fmt.Println("Continuing execution")
}
이 예제에서 readFile 함수는 파일을 열고, 파일을 처리한 후 파일을 닫습니다. 파일을 여는 도중 오류가 발생하면 panic을 호출하여 패닉 상태로 만들지만, defer를 사용해 recover를 호출하여 패닉 상태를 복구합니다. 프로그램은 계속 실행됩니다.
요약
- defer: 함수가 종료되기 직전에 실행할 코드를 지정합니다. 주로 리소스 해제에 사용됩니다.
- panic: 프로그램이 정상적으로 실행될 수 없는 상태를 나타내며, 호출되면 현재 함수의 실행이 중지되고 defer된 함수들이 실행된 후 프로그램이 종료됩니다.
- recover: 패닉 상태를 복구하여 프로그램이 계속 실행될 수 있도록 합니다. 반드시 defer 함수 내에서 호출되어야 합니다.
이러한 메커니즘을 통해 Go는 명시적이고 견고한 에러 처리를 제공합니다. defer, panic, recover를 적절히 사용하여 프로그램의 안정성과 유지보수성을 높일 수 있습니다.
GIT : https://github.com/kkaok/study-golang/tree/master/src/example/defer-panic-recover
출처 : chatGPT