1. 可排序、可比较和不可比较

  • 可排序的数据类型有三种
    • 整型Integer
    • 浮点型Floating-point
    • 字符串String
  • 可比较的数据类型除了上述三种外,还有Boolean,Complex,Pointer,Channel,Interface和Array
  • 不可比较的数据类型包括,Slice, Map, 和Function

    2. 同一个struct的2个实例比较

  • 包含不可比较的成员变量(map,slice,func等)

    • ==操作符可以比较指针,不能直接比较实例;
  • 不包含不可比较的成员变量
    • ==操作符可以比较指针和实例;
  • reflect.DeepEqual函数,指针和实例均可以比较(无论有没有包含不可比较的成员变量) ```go package main

import ( “fmt” “reflect” )

type T1 struct { Name string Age int Arr [2]bool ptr *int slice []int map1 map[string]string }

func main() { t1 := T1{ Name: “yxc”, Age: 1, Arr: [2]bool{true, false}, ptr: new(int), slice: []int{1, 2, 3}, map1: make(map[string]string, 0), }

  1. t2 := T1{
  2. Name: "yxc",
  3. Age: 1,
  4. Arr: [2]bool{true, false},
  5. ptr: new(int),
  6. slice: []int{1, 2, 3},
  7. map1: make(map[string]string, 0),
  8. }
  9. // 报错 实例不能比较 Invalid operation: t1 == t2 (operator == not defined on T1)
  10. // fmt.Println(t1 == t2)
  11. // 指针可以比较
  12. fmt.Println(&t1 == &t2) // false
  13. fmt.Println(reflect.DeepEqual(t1, t2)) // true
  14. t3 := &T1{
  15. Name: "yxc",
  16. Age: 1,
  17. Arr: [2]bool{true, false},
  18. ptr: new(int),
  19. slice: []int{1, 2, 3},
  20. map1: make(map[string]string, 0),
  21. }
  22. t4 := &T1{
  23. Name: "yxc",
  24. Age: 1,
  25. Arr: [2]bool{true, false},
  26. ptr: new(int),
  27. slice: []int{1, 2, 3},
  28. map1: make(map[string]string, 0),
  29. }
  30. fmt.Println(t3 == t4) // false
  31. fmt.Println(reflect.DeepEqual(t3, t4)) // true
  32. fmt.Printf("%p, %p \n", t3, t4) // 0xc000046050, 0xc0000460a0
  33. fmt.Printf("%p, %p \n", &t3, &t4) // 0xc000006030, 0xc000006038
  34. // 前面加*,表示指针指向的值,即结构体实例,不能用==
  35. // Invalid operation: *t3 == *t4 (operator == not defined on T1)
  36. // fmt.Println(*t3 == *t4)
  37. t5 := t3
  38. fmt.Println(t3 == t5) // true
  39. fmt.Println(reflect.DeepEqual(t3, t5)) // true
  40. fmt.Printf("%p, %p \n", t3, t5) // 0xc000046050, 0xc000046050
  41. fmt.Printf("%p, %p \n", &t3, &t5) // 0xc000006030, 0xc000006040

}

  1. <a name="XtxgV"></a>
  2. ## 3. 两个不同的struct的实例能不能比较
  3. <a name="5qa2t"></a>
  4. ### 3.1 两个struct可以相互转换,且不包含不可比较的成员变量,转换成相同类型后可以使用==操作符
  5. ```go
  6. package main
  7. import (
  8. "fmt"
  9. )
  10. type T2 struct {
  11. Name string
  12. Age int
  13. Arr [2]bool
  14. ptr *int
  15. }
  16. type T3 struct {
  17. Name string
  18. Age int
  19. Arr [2]bool
  20. ptr *int
  21. }
  22. func main() {
  23. var ss1 T2
  24. var ss2 T3
  25. // Cannot use 'ss2' (type T3) as type T2 in assignment
  26. //ss1 = ss2
  27. ss3 := T2(ss2)
  28. fmt.Println(ss3 == ss1) // true
  29. }

3.2 两个struct可以相互转换,但包含不可比较的成员变量

  • 转化成相同类型后,不可以比较实例,可以比较指针;
  • 一定要转化后再使用reflect.DeepEqual函数进行比较,否则总是返回false,失去了比较的意义; ```go package main

import ( “fmt” “reflect” )

type T2 struct { Name string Age int Arr [2]bool ptr *int map1 map[string]string }

type T3 struct { Name string Age int Arr [2]bool ptr *int map1 map[string]string }

func main() { var ss2 T2 var ss3 T3

  1. // 不同类型的struct, 不可以直接用=赋值
  2. // Cannot use 'ss2' (type T2) as type T3 in assignment
  3. // ss2 = ss3
  4. // invalid operation: &ss2 == &ss3 (mismatched types *T2 and *T3)
  5. //fmt.Println(&ss2==&ss3)
  6. // invalid operation: ss2 == ss3 (mismatched types T2 and T3)
  7. //fmt.Println(ss2==ss3)
  8. fmt.Println(reflect.DeepEqual(ss3, ss2)) // false
  9. fmt.Println(reflect.DeepEqual(&ss3, &ss2)) // false
  10. ss4 := T2(ss3)
  11. // Invalid operation: ss4==ss2 (operator == not defined on T2)
  12. //fmt.Println(ss4==ss2) //含有不可比较成员变量
  13. // 转化成相同类型后, 可以比较指针
  14. fmt.Println(&ss4==&ss2) // false
  15. fmt.Println(reflect.DeepEqual(ss4, ss2)) // true

}

  1. <a name="rC7Rl"></a>
  2. ## 4. struct可以作为map的key么?
  3. - struct必须是可比较的,才能作为key,否则编译时报错
  4. ```go
  5. package main
  6. import (
  7. "fmt"
  8. )
  9. type T1 struct {
  10. Name string
  11. Age int
  12. Arr [2]bool
  13. ptr *int
  14. //test func(i int) (err error)
  15. //slice []int
  16. //map1 map[string]string
  17. }
  18. type T2 struct {
  19. Name string
  20. Age int
  21. Arr [2]bool
  22. ptr *int
  23. }
  24. func main() {
  25. n := make(map[T2]string, 0) // 无报错
  26. fmt.Print(n) // map[]
  27. // lnvalid map key type: the comparison operators == and != must be fully defined for key type
  28. m := make(map[T1]string, 0)
  29. fmt.Println(m)
  30. }