errors.Is(err, target error)在两个错误具有相同字符串时返回false。

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

errors.Is(err, target error) returns false when the two errors have the same string

问题

这个不应该失败,因为这两个错误具有相同的字符串,但它仍然失败:

if !errors.Is(err, testspec.expectErr) {
    t.Errorf("Error mismatch, want %v, get %v", testspec.expectErr, err)
}

这是调用的 errors.Is() 函数:

func Is(err, target error) bool {
    if target == nil {
        return err == target
    }

    isComparable := reflectlite.TypeOf(target).Comparable()
    for {
        if isComparable && err == target {
            return true
        }
        if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
            return true
        }
        // TODO: consider supporting target.Is(err). This would allow
        // user-definable predicates, but also may allow for coping with sloppy
        // APIs, thereby making it easier to get away with them.
        if err = Unwrap(err); err == nil {
            return false
        }
    }
}
英文:

errors.Is(err, target error)在两个错误具有相同字符串时返回false。

This shouldn't fail because the two errors have the same string, but it still fails:

	if !errors.Is(err, testspec.expectErr) {
		t.Errorf("Error mismatch, want %v, get %v", testspec.expectErr, err)
	}

This is the errors Is() function called:

func Is(err, target error) bool {
	if target == nil {
		return err == target
	}

	isComparable := reflectlite.TypeOf(target).Comparable()
	for {
		if isComparable && err == target {
			return true
		}
		if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
			return true
		}
		// TODO: consider supporting target.Is(err). This would allow
		// user-definable predicates, but also may allow for coping with sloppy
		// APIs, thereby making it easier to get away with them.
		if err = Unwrap(err); err == nil {
			return false
		}
	}
}

答案1

得分: 3

errors.Is不会检查错误字符串是否相同。假设这些错误是使用errors.New创建的,这是有文档记录的行为:

来自https://pkg.go.dev/errors#New

func New(text string) error

New返回一个格式为给定文本的错误。即使文本相同,每次调用New都会返回一个不同的错误值。

从你在问题中添加的额外代码来看,你似乎认为两个&errorString{"block #11 not found"}的值应该相等。但这是两个指针,并且(根据语言参考中的“比较运算符”):

指针值是可比较的。如果两个指针指向同一个变量或者都具有值nil,则两个指针值相等。指向不同的零大小变量的指针可能相等,也可能不相等。

英文:

errors.Is does not check that the error strings are the same. Assuming the errors have been creating using errors.New, this is documented behavior:

From https://pkg.go.dev/errors#New

> func New(text string) error
> New returns an error that formats as the
> given text. Each call to New returns a distinct error value even if the text is identical.

From the additional code you've added to the question, it looks like you think that the two &errorString{"block #11 not found"} values should compare equal. But these are two pointers, and (from the language reference under "comparison operators"):

> Pointer values are comparable. Two pointer values are equal if they
> point to the same variable or if both have value nil.
Pointers to
> distinct zero-size variables may or may not be equal.

huangapple
  • 本文由 发表于 2022年3月26日 16:24:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/71626419.html
匿名

发表评论

匿名网友

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

确定