Можем ли мы создать подтипы для ошибок в Go? - PullRequest
0 голосов
/ 13 июня 2019

Я хочу создавать иерархические ошибки в 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, который состоит из двух подтипов, Error1 и Error1, чтобы я мог сделатьследующее.

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 Ответ

2 голосов
/ 13 июня 2019

Вы можете перечислить несколько типов в 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()
}

Какой Error1 и Error2 должны реализовывать:

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 .

Если вы хотите ограничить CommonError s, чтобы быть "истинными" ошибками, также вставьте интерфейс error:

type CommonError interface {
    error
    CommonError()
}
...