简化Go语言中的错误处理

huangapple go评论78阅读模式
英文:

Simplifying error handling in go

问题

在C和类似的语言中,可以使用以下快捷方式来检测错误并在第一个非零结果上停止:

(void)(result = dosomething() ||
       result = dosomething() ||
       result = dosomething()
)

if (result == 0 && ...

在Go语言中,似乎无法这样做。

例如:

if result = dosomething() ||
   result = dosomething(); result < 0 {
    fmt.Printf("Error occurred\n");
}

C语言可以将整数视为布尔表达式来检查非零。

例如,我可以写成:

if (result = dosomething() || ... ) 

而不是:

if ( (result = dosomething()) == 0 || ... )

但是在Go语言中,你不能这样做。

我以为我可以写成:

if result = dosomething() == 0 ||
   result = dosomething() == 0; result < 0 {
   fmt.Printf("Error occurred\n");
}

但是我得到了一个错误:

syntax error: result = dosomething() || result used as value

肯定有一种方法可以将它们链接在一起。或者按照JavaScript promises的风格,是否可以使用dosomething().doSomething.doSomething.error()的方法?

对于这个问题有什么创造性的解决方案吗?我只是想避免大量重复的代码,我想做很多事情,但如果在任何一点上出现错误,就停止执行。因为每个错误处理逻辑都完全相同。

英文:

In C and similar languages the following shortcuts can be applied to detect an error and stop on first non-zero result

(void)(result = dosomething() ||
       result = dosomething() ||
       result = dosomething()
)

if (result == 0 &amp;&amp; ...

In golang, I can't seem to do that.

For example:

if result = dosomething() ||
result = dosomething(); result < 0 {
fmt.Printf("Error occurred\n");
}

C is able to treat integers as a boolean expression when checking for non-zero.

for example I can write

if (result = dosomething() || ... ) 

Instead of

if ( (result = dosomething()) == 0 || ... )

But in go, you can't do that.

I thought I could write:

if result = dosomething() == 0 ||
   result = dosomething() == 0; result &lt; 0 {
   fmt.Printf(&quot;Error occurred\n&quot;);
}

But I get an error.

syntax error: result = dosomething() || result used as value

There has to be a way of chaining these together. Or in the style of
javascript promises could a dosomething().doSomething.doSomething.error() approach be possible?

Any creative solutions to this problem? I'm really just wanting to avoid
lots of repetitive code where I want to do a whole bunch of things, but if there is an error at any point stop. Because the error handling logic for each is exactly the same.

答案1

得分: 4

请参考错误即值这篇文章,它是由Rob Pike撰写的,介绍了一种处理函数组中错误的有趣而强大的方法,非常有效。

我之前多次使用过这种技术,确实很有效。

这种技术使用的代码示例如下(摘自文章):

// 辅助类型
type errWriter struct {
    w   io.Writer
    err error
}

func (ew *errWriter) write(buf []byte) {
    if ew.err != nil {
        return
    }
    _, ew.err = ew.w.Write(buf)
}

// 使用示例:
ew := &errWriter{w: fd}
ew.write(p0[a:b])
ew.write(p1[c:d])
ew.write(p2[e:f])
// 以此类推
if ew.err != nil {
    return ew.err
}
英文:

See Errors are values on The Go Blog. This article, written by Rob Pike, has an interesting and powerful method of handling errors in a group of functions that works very well.

I have used this technique before several times, and it really works.

For reference, the code used for this technique looks like this (copied from the article):

> // Helper type
> type errWriter struct {
> w io.Writer
> err error
> }
>
> func (ew *errWriter) write(buf []byte) {
> if ew.err != nil {
> return
> }
> _, ew.err = ew.w.Write(buf)
> }
>
> //Usage:
> ew := &errWriter{w: fd}
> ew.write(p0[a:b])
> ew.write(p1[c:d])
> ew.write(p2[e:f])
> // and so on
> if ew.err != nil {
> return ew.err
> }

答案2

得分: 1

你可以使用slicefor循环。

s := []func() error{do1,do2,do3,do4}
for i := range s {
    if err := s[i](); err != nil {
        return err
    }
}
return nil

不过,你可能应该遵循其他答案中的示例,因为它们直接来自文档。

英文:

You could use a slice and a for loop.

https://play.golang.org/p/NJaCliBydA

s := []func() error{do1,do2,do3,do4}
for i := range s {
	if err := s[i](); err != nil {
		return err
	}
}
return nil

Really though, you probably SHOULD follow the examples in the other answer as they come directly from documentation.

huangapple
  • 本文由 发表于 2017年7月28日 06:18:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/45361921.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定