Golang中空接口的比较

根据规范:

接口值具有可比性。如果两个接口值具有相同的动态类型和相等的动态值,或者两者的值为 nil,则它们是相等的。

var err error 
var reader io.Reader

据了解,errreader具有不同的动态类型(errorio.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. 我不明白如果类型不同,为什么输出相同。


人到中年有点甜
浏览 88回答 1
1回答

翻翻过去那场雪

接口值确实是可比较的,但是您只能比较可相互赋值的值(更准确地说,一个是可赋值给另一个的)。引用自规范:比较运算符:在任何比较中,第一个操作数必须可分配给第二个操作数的类型,反之亦然。您不能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 intfunc (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。
打开App,查看更多内容
随时随地看视频慕课网APP