Golang中空接口的比较
根据 界面值具有可比性。两个接口值相等,如果 它们具有相同的动态类型和相同的动态值,或者两者都具有 价值为零 据了解,Golang中空接口的比较,go,interface,comparison,Go,Interface,Comparison,根据 界面值具有可比性。两个接口值相等,如果 它们具有相同的动态类型和相同的动态值,或者两者都具有 价值为零 据了解,err和reader具有不同的动态类型(error和io.reader),因此不具有可比性 fmt.Println(err == reader) 将导致编译错误: 无效操作:err==读取器(错误和io.reader类型不匹配) 如果为真,为什么Println命令为两个变量输出相同的结果?为什么两者都是零 fmt.Printf("reader: %T", reader) //
err
和reader
具有不同的动态类型(error
和io.reader
),因此不具有可比性
fmt.Println(err == reader)
将导致编译错误:
无效操作:err==读取器(错误和io.reader类型不匹配)
如果为真,为什么Println
命令为两个变量输出相同的结果?为什么两者都是零
fmt.Printf("reader: %T", reader) // nil
fmt.Printf("error: %T", err) // nil
编辑
reflect.TypeOf(err)
或reflect.TypeOf(reader)
也将输出nil
。如果类型不同,我不理解为什么输出是相同的。接口值确实是可比较的,但您只能比较可分配给彼此的值(更准确地说,一个可分配给另一个)。引用
在任何比较中,第一个操作数必须是第二个操作数的类型,反之亦然
您不能将错误
值分配给io.Reader
,也不能将io.Reader
值分配给错误
,因此无法对它们进行比较
它们可能存储相同的动态值,也可能不存储相同的动态值。如果要比较这些值,请首先将两者转换为接口{}
,以便进行比较,例如:
fmt.Println(interface{}(err) == interface{}(reader))
这将输出(在上尝试):
注意:实际上,仅将其中一个值转换为接口{}
,就足够了,因为这样,另一个值将与您转换为接口{}
的值的类型相当(任何值都可以转换为接口{}
),因此也就足够了:
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))
现在输出将是(在上尝试):
另外,不要忘记nil
接口值并不等于持有nil
动态值的非nil
接口值。有关详细信息,请参阅
编辑:
包打印接口内的值,而不是接口值。从fmt
的包装文件中报价:
不管动词是什么,如果操作数是接口值,则使用内部具体值,而不是接口本身
与此相同:它返回动态类型,但如果您将nil
接口值传递给它,它将返回nil
,因此fmt
包将打印nil
。引用其文件:
TypeOf返回表示i的动态类型的反射类型。如果i是nil接口值,则TypeOf返回nil
的确,接口值是可比较的,但您只能比较可相互分配的值(更准确地说,一个值可分配给另一个值)。引用 在任何比较中,第一个操作数必须是第二个操作数的类型,反之亦然 您不能将
错误
值分配给io.Reader
,也不能将io.Reader
值分配给错误
,因此无法对它们进行比较
它们可能存储相同的动态值,也可能不存储相同的动态值。如果要比较这些值,请首先将两者转换为接口{}
,以便进行比较,例如:
fmt.Println(interface{}(err) == interface{}(reader))
这将输出(在上尝试):
注意:实际上,仅将其中一个值转换为接口{}
,就足够了,因为这样,另一个值将与您转换为接口{}
的值的类型相当(任何值都可以转换为接口{}
),因此也就足够了:
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))
现在输出将是(在上尝试):
另外,不要忘记nil
接口值并不等于持有nil
动态值的非nil
接口值。有关详细信息,请参阅
编辑:
包打印接口内的值,而不是接口值。从fmt
的包装文件中报价:
不管动词是什么,如果操作数是接口值,则使用内部具体值,而不是接口本身
与此相同:它返回动态类型,但如果您将nil
接口值传递给它,它将返回nil
,因此fmt
包将打印nil
。引用其文件:
TypeOf返回表示i的动态类型的反射类型。如果i是nil接口值,则TypeOf返回nil
谢谢你的回答!我编辑了我的问题来澄清这一点,你能看一下吗?但是如果
读取器
和error
的动态类型相同(nil
),为什么它们不可比较呢?@AyZu,因为它们都不可分配给另一个(它们有不同的静态类型:error
和io.reader
)。规范要求单向可分配。好的,谢谢!我混淆了静态类型和动态类型。它们具有相同的动态类型nil
,因此reflect.TypeOf()
输出相同的结果,但它们具有不同的静态类型,因此不具有可比性。谢谢您的回答!我编辑了我的问题来澄清这一点,你能看一下吗?但是如果读取器
和error
的动态类型相同(nil
),为什么它们不可比较呢?@AyZu,因为它们都不可分配给另一个(它们有不同的静态类型:error
和io.reader
)。规范要求单向可分配。好的,谢谢!我混淆了静态类型和动态类型。它们具有相同的动态类型nil
,因此