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)
    }
}
  1. 기본적으로 error형식은 인터페이스로 구현되어 있으며, 마지막으로 반환한 값을 가지고 있습니다.
  2. errors.New()함수는 주어진 에러메세지를 기반으로 error객체를 생성합니다.
  3. nil값을 기준으로해서, 에러 유무를 판단합니다.
  4. 사용자 정의(구조체) 에러타입을 생성한 후 Error()메소드를 구현할 수 있습니다.
    인자에러가 발생할 경우 사용하는 에러형식 사용자 정의 구조체를 선언하고 있습니다.
  5. &argError구조체 포인터를 생성해서 전달하고 있습니다. arg, prob 필드를 제공합니다.
  6. 함수에서 에러값을 반환하는지를 두개의 반복문을 통해서 사용하고 있습니다.
    여기서는 if문 내부에서 인라인 함수를 호출해서 에러여부를 검사하고 있으며,
    이러한 방식은 Go에서 표준적인 방식에 속합니다.
  7. 프로그래머가 임의로 에러를 정의하고 사용자 정의 에러객체로 다룰 수 있습니다.

실행하면 다음과 같습니다.

$ 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에서 에러처리에 대한 자세한 설명이 있습니다.