为什么错误消息不应该在 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
}
我对错误文本有疑问。
如果我使用如下所示的错误信息,编辑器的 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
}