错误是价值观(博客)——在逻辑上是一样的吗?

Errors are values (blog) - is logically same?

我刚刚读了 Rob Pike 写的 blog。我对此有一个小问题,可能我也可能是错的,但仍然希望获得反馈并正确理解 Go。

博客里有一段代码(其实是@jxck_写的)

_, err = fd.Write(p0[a:b])
if err != nil {
    return err
}
_, err = fd.Write(p1[c:d])
if err != nil {
    return err
}
_, err = fd.Write(p2[e:f])
if err != nil {
    return err
}
// and so on

a) 根据我的理解,如果在 fd.Write(p0[a:b]) 处发生错误,上面的代码将 return 并且永远不会执行 fd.Write(p1[c:d]) ,对吧?

罗布建议写这样的东西

var err error
write := func(buf []byte) {
    if err != nil {
        return
    }
    _, err = w.Write(buf)
}
write(p0[a:b])
write(p1[c:d])
write(p2[e:f])
// and so on
if err != nil {
    return err
}

b) 基于以上,看起来错误将 return 来自 sub 函数。所以这意味着如果错误发生在 write(p0[a:b]) 那么它仍然会执行 write(p1[c:d]),对吗?所以这意味着在逻辑上两者并不相同,对吧?

谁解释一下。

不,它们是一样的。如果 error 出现在 fd.Write(p0[a:b])err 变量将保持其值。

现在,如果您调用 write(p1[c:d]),那么 write() 函数将首先检查 err != nil 是否存在,但由于它已经存储了上一次调用中发生的 error,它将立即 return 并且不会执行进一步的代码。

a) 是的,你是对的。如果第一次写就出错,会return.

b) 否。本例中的 writeclosure。其中的 err 与外部作用域相同。所以如果第一个写入失败,另一个将简单地 return,因为外部 err 不再是 nil