2

假设我需要对具有方法的某种类型进行抽象,该方法Do返回一个error

package main

import "myproject/complex"

type Doer interface {
    Do(i int) error
}

func main() {
    var doer Doer
    doer = complex.Doer{}
    i := 1 // or any integer
    err = doer.Do(i)
    // How to check which error was returned?
}


package complex

type Doer struct{}
func (Doer) Do(i int) error {
    if i < 0 {
        return fmt.Errorf("negative numbers not allowed") // or any complex nested error but this can be expected (bad input, etc)
    }
    if i == 40 {
        return fmt.Errorf("this number cannot be used")  // or any complex nested error but this can be expected (bad input, etc)
    }
    if i > 100 {
        return fmt.Errorf("some unknown error, everything broke") // or any complex nested error which is unexpected (e. g. some 3rd party failure)
    }
}

我需要一个更好的架构来识别这是否是已知错误。我可以做到 java 风格,让实现知道我们的错误类型。例如

package do

type Doer interface {
    Do(i int) error
}

var (
    ErrNegative = fmt.Errorf("negative numbers not allowed")
    ErrCannotBeUsed = fmt.Errorf("this number cannot be used")
)


package complex

import (
    "myproject/do"
)

type Doer struct{}
func (Doer) Do(i int) error {
    if i < 0 {
        return do.ErrNegative
    }
    if i == 40 {
        return do.ErrCannotBeUsed
    }
    if i > 100 {
        return fmt.Errorf("some unknown error, everything broke")
    }
}


package main

import (
    "errors"

    "myproject/complex"
    "myproject/do"
)

func main() {
    var doer do.Doer
    doer = complex.Doer{}
    i := 1 // or any integer
    err = doer.Do(i)
    if err == nil {
        return
    }
    if errors.Is(err, do.ErrNegative) {
        // some handling
    } else if errors.Is(err, do.ErrCannotBeUsed) {
        // some handling
    } else {
        // handle unknown error
    }
}

然而,在这样的架构中,我会强制实现 ( complex.Doer) 适应接口 ( do.Doer),根据Go Wiki,这不是接口应该被使用的方式。

在这种情况下处理错误的正确方法是什么?

4

0 回答 0