package main
import "fmt"
func fn() {
defer func() {
fmt.Println(recover()) // 출력됨
}()
panic("error")
}
func main() {
fn()
fmt.Println("hello, world") // 출력됨
}
go에서 panic-defer-recover 설명할 때 자주 나오는 형태입니다
main에서 fn 호출 - 익명함수는 지연호출 - 패닉 - 지연됐던 익명함수 호출 - 익명함수 내부의 recover()에서 패닉 해결하고 리턴값 출력 - 익명함수 반환되고 main의 나머지 부분 실행
recover() 덕분에 마지막의 hello, world가 정상적으로 출력되겠죠.
그런데 fn()을 따로 정의하지 않고 main에 풀어써봅니다.
package main
import "fmt"
func main() {
defer func() {
fmt.Println(recover()) // 출력됨
}()
panic("error")
fmt.Println("hello, world") // 출력안됨
}
위와 같이 패닉 일어나고 recover가 이를 받아서 리턴값까지 출력되었는데 마지막의 hello, world가 출력이 안 됩니다.
두 예시의 차이점은 fn()으로 따로 빼서 정의했느냐 아니냐뿐인데 왜 이런 차이가 발생하는 거죠..
자문자답 : 실험결과 panic을 호출한 함수의 panic 뒷부분은 panic이 recover되도 실행되지 않습니다. 다만 panic을 호출한 함수를 호출한 함수의 뒷부분은 정상적으로 실행됩니다. 왜 이따우인지는 찾아봐도 잘 안나옵니다.
예를들어 패닉을 호출한 함수는 패닉이 해결되도 리턴을 정상적으로 못합니다. 다만 함수 정의에서 리턴값에 타입만이 아닌 리턴 변수명까지 명시해줬을 때는 예외. 아주 좆같군요.
참고로 정상적으로 리턴 못한다는 말은 리턴 자체는 하되, 리턴값의 타입의 제로밸류로 리턴하게 되는 걸 말합니다.
ㅇㅇ//되도->돼도 (되어 = 돼임) [리듬 맞춤법 봇♬]