You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言errors包中类型断言至单参数匿名接口的疑问

Go errors.Is内部断言逻辑疑问解答

疑问1:为什么能将err断言到单参数Is方法的匿名接口?

你混淆了包级函数errors.Is和自定义error类型的Is方法。

包级的errors.Is(err, target error)是两个参数的工具函数,但这里的断言err.(interface{ Is(error) bool }),检查的是err的具体类型有没有实现一个名为Is、接收一个error参数、返回bool的方法——这是自定义error类型可以实现的方法,用来让errors.Is工具函数调用它来判断当前error是否匹配target。

举个简单的自定义error例子:

type MyErr struct{}

func (e MyErr) Is(target error) bool {
    _, ok := target.(MyErr)
    return ok
}

当你调用errors.Is(MyErr{}, MyErr{})时,内部就会触发这个断言,调用MyErr.Is方法来判断匹配,而不是用默认的相等性检查。

疑问2:是否有其他类似的例外规则?

这不是例外,是Go语言鸭子类型接口的正常行为:只要类型的方法签名和接口完全一致(方法名、参数类型、返回值类型都匹配),就自动实现该接口,不需要显式声明。

除了errors.Is对应的Is(error) bool方法,Go标准库还有类似的模式:

  • errors.As工具函数会检查err的类型是否实现了As(interface{}) bool方法,用来自定义类型断言的逻辑
  • fmt.Stringer接口要求实现String() string方法,任何有这个方法的类型都可以直接用fmt.Println输出其字符串表示

验证示例代码

package main

import (
	"errors"
	"fmt"
)

type CustomErr struct {
	msg string
}

func (e CustomErr) Error() string {
	return e.msg
}

func (e CustomErr) Is(target error) bool {
	t, ok := target.(CustomErr)
	if !ok {
		return false
	}
	return e.msg == t.msg
}

func main() {
	err1 := CustomErr{msg: "test error"}
	err2 := CustomErr{msg: "test error"}
	err3 := errors.New("test error")

	fmt.Println(errors.Is(err1, err2)) // 输出 true,因为调用了CustomErr.Is
	fmt.Println(errors.Is(err1, err3)) // 输出 false
}

内容的提问来源于stack exchange,提问作者James Buzzger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 10:35:02