Go中的自定义错误处理

Go中的自定义错误处理

问题描述:

我一直在阅读this blog post,但我仍然不确定我确切地知道如何处理自定义错误,以便从我的函数返回并在其外部处理。Go中的自定义错误处理

这是目前我在做什么:

func doSomething() int { 
    x := 0 
    // Do something with x. 
    ... 
    if somethingBadHappened { 
     return -1 
    } 
    if somethingElseBadHappened { 
     return -2 
    } 
    return x 
} 

这是想什么,我在做:

func doSomething() int, ? { 
    ... 
    if somethingBadHappened { 
     return ?, err 
    } 
    if somethingElseBadHappened { 
     return ?, err2 
    } 
    return x, nil 
} 

但我不完全知道如何和什么用这些问号替换这些问号。

我会变成

func doSomething() int, ? { 
     ... 
     if somethingBadHappened { 
       return ?, err 
     } 

     if somethingElseBadHappened { 
       return ?, err2 
     } 

     return x, nil 
} 

func doSomething() (r int, err error) { 

     ... 

     if somethingBadHappened { 
       err = err1 // Whatever satisfies the `error` interface 
       return 
     } 

     if somethingElseBadHappened { 
       err = err2 // dtto 
       return 
     } 

     return x, nil 
} 

督察,在调用点它是惯用*忽略,从不使用或依赖任何其他返回值,如果err!= nil,那么只是不在乎如果上面的已经被分配了一些中间值或没有。

(*)第一个近似值,即,如果没有另行说明。例如。一个io.Reader明确声明它可以在同一时间同时返回err == io.EOF和有效的数据:

在读的时候遇到成功读取N> 0字节后错误或档案结尾状态,将返回的数量字节读取。它可能会从相同的调用中返回(非零)错误,或者从后续调用中返回错误(和n == 0)。这种一般情况的一个实例是,在输入流末尾返回非零字节数的Reader可能会返回err == EOF或err == nil。无论如何,下一次Read应返回0,EOF。

+0

嗯。为了满足错误接口,我只需要创建一个带有字符串变量的新结构类型并创建一个Error实现,对吧?或者有更简单的方法吗? – 2013-03-17 15:52:37

+0

@jnml - 不应该'return x,nil'是'return r,nil'? – 2013-03-17 18:15:34

+0

@ Ekkehard.Horner:它也可能是'return r,nil',但并不是必然的。在OP中,“x”代表一个局部变量,它在这里的意思也是如此。一般来说,最后一行可以是'return'或'reuturn expr1,expr2'。 – zzzz 2013-03-17 18:30:25

如果你不想要,你并不需要返回一个int。你可以这样做:

func doSomething() error { 
    ... 
    if somethingBadHappened { 
     return errors.New("something bad happened") 
    } 
    if somethingElseBadHappened { 
     return errors.New("something else bad happened") 
    } 
    return nil 
} 

,或者如果你想返回整数

func doSomething() (int, error) { 
    ... 
    if somethingBadHappened { 
     return -1, errors.New("something bad happened") 
    } 
    if somethingElseBadHappened { 
     return -2, errors.New("something else bad happened") 
    } 
    return x, nil 
} 

一定要import "errors"顶部。

如果你想测试你是否得到一个错误,你可以做

x, err := doSomething() 
if err != nil { 
    log.Println(err) 
}