【问题标题】:Transitive property in GolangGolang 中的传递属性
【发布时间】:2018-10-22 16:18:09
【问题描述】:

这段代码对我来说看起来很违反直觉:

var first *byte
var second interface{}

fmt.Println(first, first == nil)       // <nil> true
fmt.Println(second, second == nil)     // <nil> true
fmt.Println(first == second)           // false

据我了解,情况是第一个变量是指向byte 类型的空变量的指针,而第二个是空接口。因此,由于变量不是同一类型,因此它们不被认为是相等的。

但是如果它们彼此不相等,它们怎么可能等于某个第三个值呢?不遵守传递律时编程语言中的常见情况吗?

【问题讨论】:

标签: go equality


【解决方案1】:

标识符nil 代表通道、指针、接口、函数、映射和切片类型的zero value

*byte 的零值不等于 interface{} 的零值。

【讨论】:

    【解决方案2】:

    Nil 确实代表一个零值,但是 go 中的每个值也都有一个类型。

    当方法返回自定义错误类型为err 时,我在测试中也看到了类似的情况,然后检查错误是否相等,这会失败,因为 Go 本质上认为它们是不同的,因为您没有键入断言自定义错误类型。

    【讨论】:

      【解决方案3】:

      这里有一个更有趣的 Go 的 == 运算符不传递性示例。它不依赖于 nil;对于函数和映射等类型,最好将 x==nil 视为特殊运算符,因为这些类型的值无法相互比较。

      // "hello" != x == s == "hello" func main() { type S string var s S = "hello" var x interface{} = s fmt.Println(s == "hello") // s == "hello" fmt.Println(x == s) // x == s fmt.Println(x == "hello") // x != "hello" }

      解释这种异常的一种方法是,这里实际上有两个不同的相等运算符在起作用。第一个比较的类型是 S,但第二个和第三个比较的类型是 interface{}。一旦类型被删除,接口转换变得显式并且每个“==”被其类型的适当比较运算符替换。这些比较运算符分别是真正的等价关系,也就是说它们是传递的。

      【讨论】:

      • 谢谢你的好例子。您能否澄清为什么第三个陈述是x == "hello" 是错误的?根据规范if one operand is an untyped constant and the other operand is not, the constant is converted to the type of the other operand.如果我们将字符串常量hello转换为x,它们不应该相等吗?
      猜你喜欢
      • 1970-01-01
      • 2017-12-04
      • 1970-01-01
      • 2019-04-02
      • 2018-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多