dslfjrmz70457 2019-06-13 12:01
浏览 41
已采纳

我们可以为Go中的错误创建子类型吗?

I want to create hierarchical errors in Go. Can we achieve this in Go ? For an example, I have following two errors.

type Error1 struct {
    reason string
    cause error
}

func (error1 Error1) Error() string {
    if error1.cause == nil || error1.cause.Error() == "" {
        return fmt.Sprintf("[ERROR]: %s
", error1.reason)
    } else {
        return fmt.Sprintf("[ERROR]: %s
Caused By: %s
", error1.reason, error1.cause)
    }
}

type Error2 struct {
    reason string
    cause error
}

func (error2 Error2) Error() string {
    if error2.cause == nil || error2.cause.Error() == "" {
        return fmt.Sprintf("[ERROR]: %s
", error2.reason)
    } else {
        return fmt.Sprintf("[ERROR]: %s
Cause: %s", error2.reason, error2.cause)
    }
}

I want to have an error type CommonError which consists of two sub-types, Error1 and Error1, so that I can do the following.

func printType(param error) {
    switch t := param.(type) {
    case CommonError:
        fmt.Println("Error1 or Error 2 found")
    default:
        fmt.Println(t, " belongs to an unidentified type")
    }
}

Is there a way to achieve this ?

Edit:

In the type switch we can use multiple errors like this: case Error1, Error2: but When I have a larger number of errors, or when I need some abstraction for the errors inside a module, this approach won't be the best one.

  • 写回答

1条回答 默认 最新

  • duanhoupeng6642 2019-06-13 12:07
    关注

    You may list multiple types in a case, so this will do what you want:

    switch t := param.(type) {
    case Error1, Error2:
        fmt.Println("Error1 or Error 2 found")
    default:
        fmt.Println(t, " belongs to an unidentified type")
    }
    

    Testing it:

    printType(Error1{})
    printType(Error2{})
    printType(errors.New("other"))
    

    Output (try it on the Go Playground):

    Error1 or Error 2 found
    Error1 or Error 2 found
    other  belongs to an unidentified type
    

    If you want to "group" the errors, another solution is to create a "marker" interface:

    type CommonError interface {
        CommonError()
    }
    

    Which Error1 and Error2 must implement:

    func (Error1) CommonError() {}
    
    func (Error2) CommonError() {}
    

    And then you can do:

    switch t := param.(type) {
    case CommonError:
        fmt.Println("Error1 or Error 2 found")
    default:
        fmt.Println(t, " belongs to an unidentified type")
    }
    

    Testing it with the same, output is the same. Try it on the Go Playground.

    If you want to restrict CommonErrors to be "true" errors, also embed the error interface:

    type CommonError interface {
        error
        CommonError()
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘