【问题标题】:Can we create subtypes for errors in Go?我们可以为 Go 中的错误创建子类型吗?
【发布时间】:2019-10-28 00:29:21
【问题描述】:

我想在 Go 中创建分层错误。我们可以在 Go 中实现这一点吗? 例如,我有以下两个错误。

type Error1 struct {
    reason string
    cause error
}

func (error1 Error1) Error() string {
    if error1.cause == nil || error1.cause.Error() == "" {
        return fmt.Sprintf("[ERROR]: %s\n", error1.reason)
    } else {
        return fmt.Sprintf("[ERROR]: %s\nCaused By: %s\n", 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\n", error2.reason)
    } else {
        return fmt.Sprintf("[ERROR]: %s\nCause: %s", error2.reason, error2.cause)
    }
}

我想要一个错误类型CommonError,它包含两个子类型Error1Error1,这样我就可以执行以下操作。

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")
    }
}

有没有办法做到这一点?

编辑:

在类型切换中,我们可以使用多个错误,如下所示: case Error1, Error2: 但是当我有大量错误时,或者当我需要对模块内的错误进行一些抽象时,这种方法不会是最好的。

【问题讨论】:

  • 你可以使用case Error1, Error2:,这还不够吗?
  • 问题是当我有大量的错误时,很难把所有的错误都放在这样的地方。另一个问题是,如果我想在另一个模块中使用它,我只想对我遇到的错误进行抽象。
  • 无需自己动手:godoc.org/golang.org/x/xerrors

标签: go types error-handling subtype type-switch


【解决方案1】:

您可以在case 中列出多种类型,这样就可以满足您的需求:

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

测试它:

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

输出(在Go Playground上试试):

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

如果你想对错误进行“分组”,另一种解决方案是创建一个“标记”界面:

type CommonError interface {
    CommonError()
}

Error1Error2 必须实现:

func (Error1) CommonError() {}

func (Error2) CommonError() {}

然后你可以这样做:

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

用同样的方法测试它,输出是一样的。在Go Playground 上试试吧。

如果您想将CommonErrors 限制为“真”错误,还可以嵌入error 接口:

type CommonError interface {
    error
    CommonError()
}

【讨论】:

  • 很抱歉打扰您,但是我们可以通过这种(第二种)方法实现不同级别的错误吗?
  • @ThisaruGuruge 您可以有多个“标记”接口,例如CommonError1CommonError2 等。您也可以“组合”这些,例如CommonError2 可以嵌入CommonError1,所以如果错误是CommonError2,那也一定是CommonError1
  • 我问了一个不同的问题,如果你可以看看:stackoverflow.com/questions/56581400/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-07
  • 2010-10-13
相关资源
最近更新 更多