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

时间:2019-06-13 12:01:51

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

我想在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:,但是当我遇到大量错误或模块中的错误需要抽象时,这种方法将不是最佳方法。

1 个答案:

答案 0 :(得分:2)

您可以在<div class="big-red-button height-32 top-dialog-login-button button right" tabindex="0"> <span>Entra</span> <img alt="" class="loader" src="https://eu.static.mega.co.nz/3/images/mega/ajax-loader-white.gif"></div> 中列出多种类型,这样就可以完成您想要的操作:

GeckoElementCollection ele = geckoWebBrowser1.Document.GetElementsByTagName("div");
foreach (GeckoHtmlElement el in ele)
{
    if (el.GetAttribute("class").Equals("big-red-button height-48 login-button button right"))
    {
        el.Click();
    }
}

测试:

case

输出(在Go Playground上尝试):

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

Error1 or Error 2 found Error1 or Error 2 found other belongs to an unidentified type type CommonError interface { CommonError() } 必须实现:

Error1

然后您可以这样做:

Error2

以相同的方式测试它,输出是相同的。在Go Playground上尝试一下。

如果要将func (Error1) CommonError() {} func (Error2) CommonError() {} 限制为“ true”错误,请同时嵌入switch t := param.(type) { case CommonError: fmt.Println("Error1 or Error 2 found") default: fmt.Println(t, " belongs to an unidentified type") } 界面:

CommonError