Golang interface 比较相等
Golang 比较 interface 相等
2023-09-11 14:14:56 时间
两个 interface 比较
interface 的内部实现包含了两个字段,一个是 type,一个是 data。
第一种情况
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
}
PS E:\TEXT\test_go\test> go run .\main.go
p1 --> type: main.Profile, data: {iswbm}
p2 --> type: main.Profile, data: {iswbm}
true
p3 --> type: *main.Profile, data: 0xc000088250
p4 --> type: *main.Profile, data: 0xc000088260
false
PS E:\TEXT\test_go\test>
type 和 data 都相等
-
p1 和 p2 的 type 都是 Profile,data 都是 {“iswbm”},因此 p1 与 p2 相等。
-
p3 和 p4 虽然类型都是
*Profile
,但由于 data 存储的是结构体的地址,而两个地址和不相同,因此 p3 与 p4 不相等。
第二种情况
特殊情况:两个 interface 都是 nil
当一个 interface 的 type 和 data 都处于 unset 状态的时候,那么该 interface 的值就为 nil。
package main
import "fmt"
type ProfileInt interface {}
func main() {
var p1, p2 ProfileInt
fmt.Println(p1==p2) // true
}
* interface 与非 interface 比较
当 interface 与非 interface 比较时,会将非 interface 转换成 interface ,然后再按照两个 interface 比较的规则进行比较。
package main
import (
"fmt"
"reflect"
)
func main() {
var a string = "iswbm"
var b interface{} = "iswbm"
fmt.Println(a==b) // true
}
上面这种例子可能还好理解,那么请你看下面这个例子,为什么经过反射看到的他们不相等?
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 不相等,因此他们并不相等。
用判断方式值一样类型不一样判断相等
上面代码可以通过反射实现,但比较麻烦。
package main
import "fmt"
func main() {
var i *int = nil
var s interface{} = nil
if i == nil && s == nil {
s = i
}
if i == s {
fmt.Println("他俩相等了")
}
}
package main
import (
"fmt"
)
func main() {
var a string = "iswbm"
var b interface{} = "iswbm"
s := a
fmt.Println(s == b) // true
}
package main
import (
"fmt"
)
func main() {
var i *int = nil
var s interface{} = nil
var p interface{} = nil
if i == nil {
if s == p {
fmt.Println("相等")
return
}
}
if i != p {
fmt.Println("不相等")
}
}
反射方式
package main
import (
"fmt"
"unsafe"
)
func main() {
var i *int = nil
var p interface{} = nil
if *(*uintptr)(unsafe.Pointer(&i)) == *(*uintptr)(unsafe.Pointer(&p)) {
fmt.Println("相等")
}
}
package main
import (
"fmt"
"reflect"
)
func main() {
var i *int = nil
var s interface{} = i
eq := reflect.DeepEqual(i, s)
fmt.Println(eq) // true
}
断言方式
package main
import (
"fmt"
)
func main() {
var i *int = nil
var s interface{} = i
if i == s {
fmt.Println("相等")
}
}
相关文章
- Golang 版本发布 与 TIOBE 排名
- golang-defer坑的本质
- golang操作kafka
- golang日期时间time包代码示例: 根据生日获取年龄、生肖、星座
- golang reflect.DeepEqual深等价比较引用数据类型是否相等
- centos 配置安装golang
- 【云原生 | 37】Docker快速部署编程语言Golang
- Go语言自学系列 | golang流程控制关键字break
- golang开发区块链
- golang,函数参数传递的sync.Mutex不是指针会怎么样
- 【GoLang】golang context channel 详解
- golang 函数作为参数传递(回调)
- Golang 无法下载依赖解决方案 unrecognized import path "golang.org/x/net
- Golang gRPC实践 连载七 HTTP协议转换