reflect.DeepEqual

DeepEqual函数用来判断两个值是否深度一致。具体比较规则如下:

  • 不同类型的值永远不会深度相等
  • 当两个数组的元素对应深度相等时,两个数组深度相等
  • 当两个相同结构体的所有字段对应深度相等的时候,两个结构体深度相等
  • 当两个函数都为nil时,两个函数深度相等,其他情况不相等(相同函数也不相等)
  • 当两个interface的真实值深度相等时,两个interface深度相等
  • map的比较需要同时满足以下几个
    • 两个map都为nil或者都不为nil,并且长度要相等
    • 相同的map对象或者所有key要对应相同
    • map对应的value也要深度相等
  • 指针,满足以下其一即是深度相等
    • 两个指针满足go的==操作符
    • 两个指针指向的值是深度相等的
  • 切片,需要同时满足以下几点才是深度相等
    • 两个切片都为nil或者都不为nil,并且长度要相等
    • 两个切片底层数据指向的第一个位置要相同或者底层的元素要深度相等
    • 注意:空的切片跟nil切片是不深度相等的
  • 其他类型的值(numbers, bools, strings, channels)如果满足go的==操作符,则是深度相等的。要注意不是所有的值都深度相等于自己,例如函数,以及嵌套包含这些值的结构体,数组等

两个不同的struct的实例能不能比较

「结论」:可以比较,也不可以比较

 

可通过强制转换来比较:

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

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

func main() {
    var ss1 T2
    var ss2 T3
    // Cannot use 'ss2' (type T3) as type T2 in assignment
    //ss1 = ss2     // 不同结构体之间是不可以赋值的
    ss3 := T2(ss2)
    fmt.Println(ss3==ss1) // true
}

 

如果成员变量中含有不可比较成员变量,即使可以强制转换,也不可以比较

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 ss1 T2
    var ss2 T3
    
    ss3 := T2(ss2)
    fmt.Println(ss3==ss1)   // 含有不可比较成员变量
}

编译报错:

# command-line-arguments
./test.go:28:18: invalid operation: ss3 == ss1 (struct containing map[string]string cannot be compared)

  

问:struct可以作为map的key么

 

struct必须是可比较的,才能作为key,否则编译时报错

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

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

func main() {
    // n := make(map[T2]string, 0) // 无报错
    // fmt.Print(n)                // map[]

    m := make(map[T1]string, 0)
    fmt.Println(m) // invalid map key type T1
}