基本类型
基本类型比较中变量类型必须相等(即使是int、int32这种也是不能比较的)
var a int
b := 0
fmt.Println(a==b) //true
var c int32
fmt.Println(a==c) // 无法比较int与int32将在编译时报错
type INT int
var d INT
fmt.Println(a==d) // 无法比较int与INT(即使实际都是int),将在编译时报错
type aliasInt = int
var e aliasInt
fmt.Println(a==e) // 类型别名,能够比较。 true
也即
- 变量类型必须相等才能比较
- 类型再定义也不能比较
- int、int32等接近类型也不能比较
- 类型别名能够比较
数组类型
对于数组而言,要求数组中所有数据必须是可比较的,且数组长度也要一致
var a [1]string
var b [2]string
fmt.Println(a == b) // 数组长度不一致,不能比较
var c [1]int
fmt.Println(a == c) // 数组元素类型不一致,也不能比较
var d [1]string
fmt.Println(a == d) //只有数组元素类型一致,且长度相等才能比较,但
var e [1][]string
var f [1][]string
fmt.Println(e == f) // 若数组元素是不可比较类型,那么数组也不可以比较
总之对于能比较数组必须满足
- 数组长度一致
- 数组元素类型一致,且能比较
结构体类型
结构体类型只要结构成员是能比较的,那么结构体就能比较
type cmp struct {
x int
y string
}
a := cmp{
x: 0,
y: "",
}
b := cmp{
x: 0,
y: "",
}
fmt.Println(a == b) // 此时cmp结构所有成员都可以比较,因此结构之间也能比较
type notCmp struct {
x int
y []string
}
c := notCmp{
x: 0,
y: nil,
}
d := notCmp{
x: 0,
y: nil,
}
fmt.Println(c == d) // 此时nocmp结构中含有不可比较的slice类型,那么结构便不能比较
指针类型
指针类型是基本类型指针以及slice、map。对于基本类型指针比较的是指针指向的是否为同一个地址
而slice、map则无法比较
var o int
a := &o
b := &o
fmt.Println(a == b) // true
var o1 int
c := &o1
fmt.Println(a == c) // false
type simple struct {
x int
y string
}
d := &simple{}
f := &simple{}
g := d
fmt.Println(d == f) // false
fmt.Println(d == g) // true
interface{}类型
接口比较的是动态类型以及动态值,只有两者都相等时,比较才相等。
动态类型就是实际实现接口的结构类型,动态值就是实际实现接口的结构体
// 此时w声明为io.Writer接口,但并没有动态类型、动态值 var w io.Writer // 此时w有了动态类型*os.File,但由于f也只是个声明因此还没有动态值 var f *os.File w = f // 此时w才真的有了动态值 w = &os.File{}
type Person interface {
getName() string
}
type student struct {
Name string
}
type teacher struct {
Name string
}
func (s student) getName() string {
return s.Name
}
func (t teacher) getName() string {
return t.Name
}
const name = "xiaoming"
func comparePerson(p1, p2 Person) bool {
return p1 == p2
}
// student和teacher尽管继承同一个接口,拥有相同的属性、方法以及值,可是他们类型不同,所以仍然是不相等的
s1 := student{Name: name}
s2 := student{Name: name}
fmt.Println(comparePerson(s1, s2)) // true
t1 := teacher{Name: name}
fmt.Println(comparePerson(s1, t1)) // false
如果动态类型不能比较的话,那么也会不相等
type mapStudent map[string]string
type mapTeacher map[string]string
func (m mapStudent) getName() string {
return m["key"]
}
func (m mapTeacher) getName() string {
return m["key"]
}
ms1 := mapStudent{
"key": name,
}
ms2 := mapTeacher{
"key": name,
}
fmt.Println(comparePerson(ms1, ms2)) // false
函数类型
函数不可比较。
对于使用reflect.DeepEqual去硬比较,只要是两个不全是nil,返回结果都是不相等
硬要比较——slice、map
- 对于byte slice类型,可以通过bytes.Equal进行比较
- reflect.DeepEqual可以比较任意类型变量
- 当然还可以引入第三方库进行比较
Ref