为了账号安全,请及时绑定邮箱和手机立即绑定

Golang中空接口的比较

Golang中空接口的比较

Go
人到中年有点甜 2023-05-22 17:42:24
根据规范:接口值具有可比性。如果两个接口值具有相同的动态类型和相等的动态值,或者两者的值为 nil,则它们是相等的。var err error  var reader io.Reader据了解,err和reader具有不同的动态类型(error和io.Reader),因此没有可比性。fmt.Println(err == reader)会导致编译错误:无效操作:err == reader(错误类型与 io.Reader 不匹配)如果是这样,为什么Println命令对两个变量输出相同的结果?为什么两者都是nil?fmt.Printf("reader: %T", reader) // nil fmt.Printf("error: %T", err) // nil编辑 reflect.TypeOf(err)或reflect.TypeOf(reader)也将输出nil. 我不明白如果类型不同,为什么输出相同。
查看完整描述

1 回答

?
翻翻过去那场雪

TA贡献2065条经验 获得超13个赞

接口值确实是可比较的,但是您只能比较可相互赋值的值(更准确地说,一个是可赋值给另一个的)。引用自规范:比较运算符:

在任何比较中,第一个操作数必须可分配给第二个操作数的类型,反之亦然。

您不能error为 an 赋值io.Reader,也不能io.Reader为 an 赋值error,因此无法比较它们。

它们可能存储也可能不存储相同的动态值,如果你想比较它们,首先将两者都隐藏到interface{},这样你就可以比较它们,例如:

fmt.Println(interface{}(err) == interface{}(reader))

这将输出(在Go Playground上尝试):

true

注意:实际上只将其中一个转换为 就足够了interface{},因为这样另一个值将与您转换为的值的类型相当interface{}(任何值都可以转换为interface{}),所以这样做也足够了:

fmt.Println(interface{}(err) == reader)

测试与非接口值的比较nil

type x int


func (x) Error() string            { return "" }

func (x) Read([]byte) (int, error) { return 0, nil }


err = x(0)

reader = x(0)

fmt.Println(interface{}(err) == interface{}(reader))


reader = x(1)

fmt.Println(interface{}(err) == interface{}(reader))

现在输出将是(在Go Playground上尝试):

true
false

也不要忘记nil接口值不等于nil持有nil动态值的非接口值。

编辑:

fmt打印接口内的值,而不是接口值。引用包文档fmt

无论动词如何,如果操作数是接口值,则使用内部具体值,而不是接口本身。

同样适用于reflect.TypeOf():它返回动态类型,但如果您将nil接口值传递给它,它会返回nil,因此fmt包将打印nil。引用它的文档:

TypeOf 返回表示 i 的动态类型的反射类型。如果 i 是 nil 接口值,则 TypeOf 返回 nil。


查看完整回答
反对 回复 2023-05-22
  • 1 回答
  • 0 关注
  • 108 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信