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

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

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

问题

我对错误文本有一个问题。

如果我使用下面显示的错误消息,编辑器的代码检查器会给出一个警告,警告内容是:“错误字符串不应以标点符号或换行符结尾”:

return errors.New("Test!")
                       ^

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

英文:

I have a problem with error text.

If I use the error message shown below, the editor's linter gives a warning like this: "error strings should not end with punctuation or a newline":

return errors.New("Test!")
                       ^

The question is: why shouldn't I use punctuation? What is the real reason behind it?

答案1

得分: 20

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

正如注释中的链接所说:

> 错误字符串不应该大写(除非以专有名词或缩写开头)或以标点符号结尾,因为它们通常是在其他上下文之后打印的。

举个例子,考虑以下程序:

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 
}

Playground: https://play.golang.org/p/dxI2301IX1P

英文:

Errors may be wrapped up the call stack and their messages may be concatenated before printing. If you add punctuation, the end result might be weird from a grammatical standpoint.

As the link in the comment says:

> 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.

As an example, consider the following program:

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")
}

Of course this example is contrived, but the point is that in a real-world scenario you don't know how your libraries — or users of your code — will format their errors. The issue is probably easier to demonstrate with the error package "github.com/pkg/errors", where each call to Wrap results in a colon (:) separator when printing the message:

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 
}

Playground: https://play.golang.org/p/dxI2301IX1P

huangapple
  • 本文由 发表于 2021年8月15日 22:56:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/68792696.html
匿名

发表评论

匿名网友

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

确定