Golang中空接口之间的比较 [英] Comparison between empty interfaces in Golang

查看:114
本文介绍了Golang中空接口之间的比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据规范:

接口值是可比较的.如果两个接口值相等它们具有相同的动态类型和相等的动态值,或者值为零.

Interface values are comparable. Two interface values are equal if they have identical dynamic types and equal dynamic values or if both have value nil.

var err error 
var reader io.Reader                           

据了解, err reader 具有不同的动态类型( error io.Reader )因此不可比.

As far as understand, err and reader have different dynamic types (error and io.Reader) and therefore are not comparable.

fmt.Println(err == reader) 

将导致编译错误:

无效操作:err == reader(错误类型和io.Reader的不匹配)

invalid operation: err == reader (mismatched types error and io.Reader)

如果为真,为什么 Println 命令为两个变量输出相同的结果?为什么两者都是 nil ?

If it is true, why Println command outputs the same results for both variables? Why both are nil?

fmt.Printf("reader: %T", reader) // nil
fmt.Printf("error: %T", err) // nil

编辑 reflect.TypeOf(err) reflect.TypeOf(reader)也将输出 nil .我不明白如果类型不同,为什么输出也一样.

EDIT reflect.TypeOf(err)or reflect.TypeOf(reader) will also output nil. I do not understand why the output is the same if the types are different.

推荐答案

确实,接口值是可比较的,但是您只能比较可分配给彼此的值(更确切地说,一个可分配给另一个).引用自规范:比较运算符:

It's true that interface values are comparable, but you can only compare values that are assignable to each other (more precisely, one is assignable to the other). Quoting from Spec: Comparison operators:

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

您不能将 error 值分配给 io.Reader ,也不能将 io.Reader 值分配给还是 error ,所以您无法比较它们.

You can't assign an error value to an io.Reader, and you can't assign an io.Reader value to an error either, so you can't compare them.

如果您想比较它们,它们可能会或可能不会存储相同的动态值,请先将它们都隐藏到 interface {} 中,以便进行比较,例如:

They may or may not store the same dynamic value, if you want to compare those, first covert both to interface{}, so you can compare them, e.g.:

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

这将输出(在游乐场上尝试):

This will output (try it on the Go Playground):

true

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

Note: actually it would be enough to convert only one of them to interface{}, because that way the the other value will become comparable to the type of the one you converted to interface{} (any value is convertible to interface{}), so it would also be enough to do:

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

使用非 nil 接口值测试比较:

Testing the comparison with non-nil interface values:

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))

现在将输出(在进入游乐场上尝试):

Now output will be (try it on the Go Playground):

true
false

也不要忘记一个 nil 接口值不等于一个非< nil 接口值,该接口值包含一个 nil 动态值.有关详细信息,请参见隐藏nil值,了解为何golang失败这里

Also don't forget that a nil interface value does not equal to a non-nil interface value holding a nil dynamic value. For details, see Hiding nil values, understanding why golang fails here

fmt 包在界面内部打印值,而不是接口值.引用 fmt 的软件包文档:

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

Regardless of the verb, if an operand is an interface value, the internal concrete value is used, not the interface itself.

reflect.TypeOf() 也一样:它返回动态类型,但是如果您向其传递 nil 接口值,它将返回 nil ,因此 fmt 软件包将打印.引用其文档:

Same goes with reflect.TypeOf(): it returns the dynamic type, but if you pass a nil interface value to it, it returns nil so the fmt package will print nil. Quoting its doc:

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

TypeOf returns the reflection Type that represents the dynamic type of i. If i is a nil interface value, TypeOf returns nil.

这篇关于Golang中空接口之间的比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆