Reputation: 362
I am learning how error comparison works in Go and found something I cannot understand.
Function errors.Is(err, target error)
checks if target is Comparable.
func Is(err, target error) bool {
if target == nil {
return err == target
}
isComparable := reflectlite.TypeOf(target).Comparable()
for {
if isComparable && err == target {
return true
}
Which case does this call handle given that all interfaces in Go are comparable and error
is an interface?
Upvotes: 1
Views: 231
Reputation: 120951
Interfaces values are comparable, but the comparison can panic at run-time. The specification says:
A comparison of two interface values with identical dynamic types causes a run-time panic if values of that type are not comparable.
The check prevents a panic by skipping the comparison when the target's concrete type is not comparable.
Here's an example:
type E []byte
func (e E) Error() string { return string(e) }
func (e E) Is(target error) bool {
t, ok := target.(E)
return ok && bytes.Equal(e, t)
}
var a error = E{}
var b error = E{}
fmt.Println(errors.Is(a, b)) // prints true
fmt.Println(a == b) // panics because slices are not comparable
Upvotes: 5