2019年7月15日月曜日

golang でカスタム error のフィールドにアクセスする方法

概要

基本的に error は Error() という関数を実装しその関数だけを呼び出します
しかし自分で作成したカスタム error のフィールドに直接アクセスしたい場合があると思います

環境

  • macOS 10.14.5
  • golang 1.11.5

サンプルコード

  • vim main.go
package main

import (
    "fmt"
    "reflect"
)

type MyError struct {
    msg  string
    code int
}

func (e *MyError) Error() string {
    return fmt.Sprintf("code: %d, msg: %s", e.code, e.msg)
}

func genError() error {
    return &MyError{"this is my error", 400}
}

func main() {
    err := genError()
    if err != nil {
        fmt.Println(err)
        fmt.Println(reflect.TypeOf(err))
        fmt.Println(err.(*MyError).msg)
        fmt.Println(err.(*MyError).code)
    }
}

説明

ポイントは error から MyError を取得するところです
err.(*MyError) という呼び出しをすることで直接カスタムエラーにアクセスすることができます

これを応用すればカスタムエラーに関数を実装してそれを呼び出すことも可能です

package main

import (
    "fmt"
)

type MyError struct {
    msg  string
    code int
}

func (e *MyError) Error() string {
    return fmt.Sprintf("code: %d, msg: %s", e.code, e.msg)
}

func (e *MyError) DoubleCode() int {
    return e.code * 2
}

func genError() error {
    return &MyError{"this is my error", 400}
}

func main() {
    err := genError()
    if err != nil {
        fmt.Println(err.(*MyError).DoubleCode())
    }
}

Type Assertion

この参照の仕方は Type Assertion と言います
簡単に言えばキャストですがインタフェース用のキャストになります
golang の error はインタフェースなのでそれを MyError にキャストするのに Type Assertion を使っている感じです

参考サイト

0 件のコメント:

コメントを投稿