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

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

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

问题

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

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

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

  1. func Is(err, target error) bool {
  2. if target == nil {
  3. return err == target
  4. }
  5. isComparable := reflectlite.TypeOf(target).Comparable()
  6. for {
  7. if isComparable && err == target {
  8. return true
  9. }
  10. if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
  11. return true
  12. }
  13. // TODO: consider supporting target.Is(err). This would allow
  14. // user-definable predicates, but also may allow for coping with sloppy
  15. // APIs, thereby making it easier to get away with them.
  16. if err = Unwrap(err); err == nil {
  17. return false
  18. }
  19. }
  20. }
英文:

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

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

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

This is the errors Is() function called:

  1. func Is(err, target error) bool {
  2. if target == nil {
  3. return err == target
  4. }
  5. isComparable := reflectlite.TypeOf(target).Comparable()
  6. for {
  7. if isComparable && err == target {
  8. return true
  9. }
  10. if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
  11. return true
  12. }
  13. // TODO: consider supporting target.Is(err). This would allow
  14. // user-definable predicates, but also may allow for coping with sloppy
  15. // APIs, thereby making it easier to get away with them.
  16. if err = Unwrap(err); err == nil {
  17. return false
  18. }
  19. }
  20. }

答案1

得分: 3

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

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

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

确定