3.7 Go 里是怎么比较相等与否? ============================= 1. 两个 interface 比较 ---------------------- interface 的内部实现包含了两个字段,一个是 type,一个是 data |image0| 因此两个 interface 比较,势必与这两个字段有所关系。 经过验证,只有下面两种情况,两个 interface 才会相等。 第一种情况 ~~~~~~~~~~ **type 和 data 都相等** 在下面的代码中,p1 和 p2 的 type 都是 Profile,data 都是 ``{"iswbm"}``\ ,因此 p1 与 p2 相等 而 p3 和 p3 虽然类型都是 ``*Profile``\ ,但由于 data 存储的是结构体的地址,而两个地址和不相同,因此 p3 与 p4 不相等 .. code:: go package main import "fmt" type Profile struct { Name string } type ProfileInt interface {} func main() { var p1, p2 ProfileInt = Profile{"iswbm"}, Profile{"iswbm"} var p3, p4 ProfileInt = &Profile{"iswbm"}, &Profile{"iswbm"} fmt.Printf("p1 --> type: %T, data: %v \n", p1, p1) fmt.Printf("p2 --> type: %T, data: %v \n", p2, p2) fmt.Println(p1 == p2) // true fmt.Printf("p3 --> type: %T, data: %p \n", p3, p3) fmt.Printf("p4 --> type: %T, data: %p \n", p4, p4) fmt.Println(p3 == p4) // false } 运行后,输出如下 :: p1 --> type: main.Profile, data: {iswbm} p2 --> type: main.Profile, data: {iswbm} true p3 --> type: *main.Profile, data: 0xc00008e200 p4 --> type: *main.Profile, data: 0xc00008e210 false 第二种情况 ~~~~~~~~~~ **特殊情况:两个 interface 都是 nil** 当一个 interface 的 type 和 data 都处于 unset 状态的时候,那么该 interface 的值就为 nil .. code:: go package main import "fmt" type ProfileInt interface {} func main() { var p1, p2 ProfileInt fmt.Println(p1==p2) // true } 2. interface 与 非 interface 比较 --------------------------------- 当 interface 与非 interface 比较时,会将 非interface 转换成 interface ,然后再按照 **两个 interface 比较** 的规则进行比较。 示例如下 .. code:: go package main import ( "fmt" "reflect" ) func main() { var a string = "iswbm" var b interface{} = "iswbm" fmt.Println(a==b) // true } 上面这种例子可能还好理解,那么请你看下面这个例子,为什么经过反射看到的他们不相等? .. code:: go package main import ( "fmt" "reflect" ) func main() { var a *string = nil var b interface{} = a fmt.Println(b==nil) // false } 因此当 nil 转换为interface 后是 ``(type=nil, data=nil)`` ,这与 b ``(type=*string, data=nil)`` 虽然 data 是一样的,但 type 不相等,因此他们并不相等。 .. |image0| image:: http://image.iswbm.com/20200610235106.png