如何忽略GO中的返回错误

时间:2015-06-24 13:12:37

标签: go

我今天开始学习Go 有一件事让我发疯,它是err返回的参数。

我们假设我需要嵌套一些函数。像这样:

return string(json.Marshal(MyData))

或更复杂的例子:

return func1(func2(func3(MyData)))

是否真的有必要写:

tmp1 , _ = func3(MyData)
tmp2 , _ = func2(tmp1)
tmp3 , _ = func1(tmp2)
return tmp3

那很烦人! 有没有办法让代码看起来更干净?

3 个答案:

答案 0 :(得分:5)

真正的答案是:不要。

永远不要忽略错误。

严重。错误是有原因的。如果函数返回错误, 它几乎总是意味着在你的程序运行期间,它是可能的, 即使它是100%无错误的,因为该功能失败。如果确实如此, 你通常不想继续前进,好像什么都没发生一样。

如果你完全确定你正在使用某个功能,以确保它永远不会返回一个非零错误(除非你的程序中有错误,并且始终存在is),您可能希望编写一个Must样式的函数,就像在template package中一样,它会返回错误值。

错误处理不是噪音。这不是混乱。这不是你想要的东西 摆脱。如果看起来50%的程序是错误的 处理,这是因为50%的程序是,应该是错误处理。

答案 1 :(得分:1)

可以定义一个忽略错误的函数,但是Go缺少泛型使得你不得不在整个地方使用接口{}和类型转换,失去了很多静态保证来自typechecker的过程。这非常难看。不要这样做。

func ignoreError(val interface {}, err error) interface {} {
    return val
}

每次调用ignoreError()时,您都必须对预期的返回类型进行类型转换。

Playground example

答案 2 :(得分:0)

您经常会看到的一种可能的抽象模式是使用通用错误处理程序。

这并不能防止您必须处理错误值,但可以抽象处理错误而不涉及其余代码。

请注意,将此类抽象视为“非惯用的” Go,“纯”方式是明确地就地处理错误。但是,这种由恐慌驱动的替代方案仍然非常有用,特别是对于快速制作原型脚本的情况,在该脚本中您只想将所有错误转储到控制台或日志文件中。

对于可重用的程序包,我会坚持使用冗长的显式方式,因为其他人希望产生错误的函数实际返回错误值,而不是使用紧急恢复机制。

package main

import (
    utils
)

func main() {
    defer func() {
        utils.Handle(func(err error) {
            // Handle errors in a generic way, 
            // for example using println, or writing to http 
        })
    }()

    var result, err := someFragileFunction()
    Check(err)
}
package utils

func Check(err error) {
    if err != nil {
        panic(err)
    }
}

func Handle(handler func(err error))  {
    if r := recover(); r != nil {
        if err, ok := r.(error); ok {
            handler(err)
        } else {
            panic(r)
        }
    }
}