目录

go 类型直接比较

结构体能否比较?数组能否比较?slice、map、channel能否比较?接口能否比较?函数能否比较?

结构体比较

能用"==“直接比较的我们才称其为能比较。

类型不同的都不能直接比较,类型别名可以。不同类型可以先强转再比较。 相同类型时,字段都是可比较类型才能直接比较。

type T2 struct {
	Name string
	Age  int
}
type T22 T2
type T222 = T2
type T3 struct {
	Name string
	Age  int
}

func main() {
	t2 := T2{}
	t22 := T22{}
	t222 := T222{}
	t3 := T3{}
	fmt.Println(t2==t222) // =起别名能比较
	fmt.Println(t2==t22) // 类型定义不能比较
	fmt.Println(t2==t3) // 不同类型,哪怕字段完全相同不能比较
	t33:=T3(t2)
	fmt.Println(t3==t33) // 不同类型,可以先强转再比较
}

结构体字段顺序、类型、字段名完全相同才可以强转。

数组比较

数组可以直接比较。前提是数组长度和类型相同,而且数组里面的元素是可以直接比较的。

func main() {
	arr1:=[2]int{}
	arr2:=[2]int{}
	fmt.Println(arr1==arr2) // 可以比较

	arr11:=[2][]int{}
	arr22:=[2][]int{}
	fmt.Println(arr11==arr22) // invalid operation: arr11 == arr22 ([2][]int cannot be compared)
}

channel比较

channel可以直接比较,比较的是channel的地址

func main() {
	c1:=make(chan int)
	c2:=make(chan int)
	c11:=make(chan []int)
	c22:=make(chan []int)
	fmt.Println(c1==c2) // false
	fmt.Println(c11==c22) // false
}

slice、map比较

slice不能直接比较。slice之间之所以不能进行比较,是因为slice的元素是间接引用的。slice引用的底层数组的元素随时可能会被修改,即slice在不同的时间可能包含不同的值,所以无法进行比较。 map不能直接比较。

接口比较

接口类型的变量,包含该接口变量存储的值和值的类型两部分组成,分别称为接口的动态类型和动态值。只有动态类型和动态值都相同时,两个接口变量才相同

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
}

func compare(s, t Person) bool {
    return s == t
}

func main() {

    s1 := Student{"minping"}
    s2 := Student{"minping"}
    t := Teacher{"minping"}

    fmt.Println(compare(s1, s2)) //true
    fmt.Println(compare(s1, t))  //false,类型不同
}

接口的动态类型必须要是可比较的,如果不能比较(比如slice,map),则运行时会报panic。因为编译器在编译时无法获取接口的动态类型,所以编译能通过,但是运行时直接panic

函数比较

golang的func作为一等公民,也是一种类型,而且不可比较

type GetName func ()
type GetName2 func ()
func main() {
	var f1 GetName
	var f2 GetName
	fmt.Println(f1==f2) // invalid operation: f1 == f2 (func can only be compared to nil)
}

总结

1.结构体等复合类型,只有每个元素(成员)可比较且相同类型时能比较。类型和值都相等时,两个复合元素才相等 2.slice,map不可比较,但是可以用reflect或者cmp包来比较 3.func作为golnag的一等公民,也是一个类型,也不能比较。 4.channel引用类型的比较是看指向的是不是同一个变量 5.类型再定义(type A string)不可比较,是两种不同的类型 6.类型别名(type A = string)可比较,是同一种类型。 7.reflect.DeepEqual函数可以用来比较两个任意类型的变量