为什么错误消息不应该在 Go 中以标点符号结尾?

Why error messages shouldn't end with a punctuation mark in Go?

我对错误文本有疑问。

如果我使用如下所示的错误信息,编辑器的 linter 会给出这样的警告:"error strings should not end with punctuation or a newline":

return errors.New("Test!")
                       ^

问题是:为什么我不应该使用标点符号?背后的真正原因是什么?

错误可能会包含在调用堆栈中,并且它们的消息可能会在打印前连接起来。如果您添加标点符号,从语法的角度来看,最终结果可能会很奇怪。

正如评论中的 link 所说:

Error strings should not be capitalized (unless beginning with proper nouns or acronyms) or end with punctuation, since they are usually printed following other context.

例如,考虑以下程序:

func main() {
    fmt.Println(foo()) // bar failed: baz failed!: some problem
}

func foo() error {
    err := bar()
    if err != nil {
        return fmt.Errorf("%s: %w", "bar failed", err)
    }
    return nil
}

func bar() error {
    err := baz()
    if err != nil {
        return fmt.Errorf("%s: %w", "baz failed!", err)
    }
    return nil
}

func baz() error {
    return errors.New("some problem")
}

当然这个例子是人为设计的,但关键是在现实世界中你不知道你的库——或者你的代码的用户——将如何格式化他们的错误。使用错误包 "github.com/pkg/errors" 可能更容易证明该问题,其中每次调用 Wrap 都会在打印消息时产生冒号 (:) 分隔符:

package main

import (
    "github.com/pkg/errors"
    "fmt"
)

func main() {
    fmt.Println(errors.Wrap(errors.Wrap(errors.Wrap(errors.New("foo"), "bar"), "baz"), "quux"))
    // quux: baz: bar: foo 
}

游乐场:https://play.golang.org/p/dxI2301IX1P