Go by Example: [21] Errors
Errors
Go
언어에서는 에러또한 명시적으로 사용하는 하나의 형태입니다. 암시적으로 함수의
반환값으로 포함되기도 합니다. Java / Ruby와 같은 언어의 예외와 C
언어의 단일 결과값으로
에러유무를 처리하는 것과는 대조적입니다. 함수호출의 결과를 에러형식으로 전달하는 것은
상당히 유연하게 프로그램을 작성할 수 있는 기능 중 하나입니다.
package main
import "errors"
import "fmt"
func f1(arg int) (int, error) { // [1]
if arg == 42 {
return -1, errors.New("can't work with 42") // [2]
}
return arg + 3, nil // [3]
}
type argError struct { // [4]
arg int
prob string
}
func (e *argError) Error() string {
return fmt.Sprintf("%d - %s", e.arg, e.prob)
}
func f2(arg int) (int, error) {
if arg == 42 {
return -1, &argError{arg, "can't work with it"} // [5]
}
return arg + 3, nil
}
func main() {
for _, i := range []int{7, 42} { // [6]
if r, e := f1(i); e != nil {
fmt.Println("f1 failed:", e)
} else {
fmt.Println("f1 worked:", r)
}
}
for _, i := range []int{7, 42} {
if r, e := f2(i); e != nil {
fmt.Println("f2 failed:", e)
} else {
fmt.Println("f2 worked:", r)
}
}
_, e := f2(42) // [7]
if ae, ok := e.(*argError); ok {
fmt.Println(ae.arg)
fmt.Println(ae.prob)
}
}
- 기본적으로
error
형식은 인터페이스로 구현되어 있으며, 마지막으로 반환한 값을 가지고 있습니다. errors.New()
함수는 주어진 에러메세지를 기반으로error
객체를 생성합니다.nil
값을 기준으로해서, 에러 유무를 판단합니다.- 사용자 정의(구조체) 에러타입을 생성한 후
Error()
메소드를 구현할 수 있습니다.
인자에러가 발생할 경우 사용하는 에러형식 사용자 정의 구조체를 선언하고 있습니다. &argError
구조체 포인터를 생성해서 전달하고 있습니다.arg
,prob
필드를 제공합니다.- 함수에서 에러값을 반환하는지를 두개의 반복문을 통해서 사용하고 있습니다.
여기서는if
문 내부에서 인라인 함수를 호출해서 에러여부를 검사하고 있으며,
이러한 방식은Go
에서 표준적인 방식에 속합니다. - 프로그래머가 임의로 에러를 정의하고 사용자 정의 에러객체로 다룰 수 있습니다.
실행하면 다음과 같습니다.
$ go run errors.go
f1 worked: 10
f1 failed: can't work with 42
f2 worked: 10
f2 failed: 42 - can't work with it
42
can't work with it
Go Team Blog에서 에러처리에 대한 자세한 설명이 있습니다.