🔥 연습문제 - 에러 처리하기

358자
4분

Go 언어에서 오류 처리는 매우 중요한 부분이에요. 이번 예제에서는 앞서 다뤘던 Sqrt 함수를 수정하여 오류 처리를 추가해 볼게요.

기존 Sqrt 함수

func Sqrt(x float64) float64 {
	z := 1.0
	prevZ := 0.0
	for {
		z -= (z*z - x) / (2*z)
		if abs(z - prevZ) < 1e-10 { // z 값의 변화가 충분히 작으면 반복 종료
			break
		}
		prevZ = z
	}
	return z
}
 
func abs(x float64) float64 {
	if x < 0 {
		return -x
	}
	return x
}
 
go

위 코드는 이전에 작성했던 Sqrt 함수입니다. 이 함수를 수정하여 x가 음수일 경우 오류를 반환하도록 수정해 보겠습니다.

음수에 대한 오류 처리

Sqrt 함수는 복소수를 지원하지 않기 때문에, 음수가 주어졌을 때는 nil이 아닌 오류 값을 반환해야 해요.

새로운 타입 정의하기

type ErrNegativeSqrt float64
 
go

위와 같이 새로운 타입 ErrNegativeSqrt를 정의해 주세요. 그리고 이 타입에 error 인터페이스를 구현하는 메서드를 추가해 볼 거예요.

func (e ErrNegativeSqrt) Error() string
text

이 메서드를 구현하면 ErrNegativeSqrt(-2).Error()를 호출했을 때 "cannot Sqrt negative number: -2"와 같은 문자열을 반환하게 돼요.

주의사항: Error 메서드 내에서 fmt.Sprint(e)를 호출하면 프로그램이 무한 루프에 빠질 수 있어요. 이를 피하려면 e를 먼저 변환해야 해요: fmt.Sprint(float64(e)). 왜 그럴까요?

Sqrt 함수 수정하기

이제 Sqrt 함수를 수정하여 음수가 주어졌을 때 ErrNegativeSqrt 값을 반환하도록 해 볼 거예요.

package main
 
import (
	"fmt"
)
 
func Sqrt(x float64) (float64, error) {
	// 음수인 경우 오류 반환
	if x < 0 {
		return 0, ErrNegativeSqrt(x)
	}
 
	z := 1.0
	prevZ := 0.0
	for {
		z -= (z*z - x) / (2*z)
		if abs(z - prevZ) < 1e-10 { // z 값의 변화가 충분히 작으면 반복 종료
			break
		}
		prevZ = z
	}
	return z, nil
}
 
func abs(x float64) float64 {
	if x < 0 {
		return -x
	}
	return x
}
 
type ErrNegativeSqrt float64
 
func (e ErrNegativeSqrt) Error() string {
	return fmt.Sprintf("cannot Sqrt negative number: %v", float64(e))
}
 
func main() {
	fmt.Println(Sqrt(2))
	fmt.Println(Sqrt(-2))
}
 
go

위 코드에서는 기존 Sqrt 함수를 수정하여 음수인 경우 ErrNegativeSqrt 오류를 반환하도록 했어요. 그리고 ErrNegativeSqrt 타입에 Error 메서드를 구현하여 오류 메시지를 생성하도록 했죠.

main 함수에서는 Sqrt 함수를 호출하여 결과를 출력해 봤어요. 양수인 경우에는 제곱근 값과 nil 오류를 반환하고, 음수인 경우에는 0과 ErrNegativeSqrt 오류를 반환합니다.