当前位置:网站首页>Analysis and comprehensive summary of full type equivalent judgment in go
Analysis and comprehensive summary of full type equivalent judgment in go
2022-06-25 23:35:00 【_ Qilixiang】
go Equivalence judgment in mainly includes == and DeepEqual operation , Next, let's see what's going on , What's the trick .
This article summarizes all possible cases and conclusions , If help 、 Welcome to collect !
Catalog
Typical code - With attributes struct
map
Typical code
func CompareMapDeepEqual() {
var m1, m2 map[string]int
//fmt.Println("a10==a20: ", m1 == m2) // Invalid operation: m1 == m2 (the operator == is not defined on map[string]int)
fmt.Println("DeepEqual(m1,m2): ", reflect.DeepEqual(m1, m2))
var m11, m21 map[string]*int
fmt.Println("DeepEqual(m11,m21): ", reflect.DeepEqual(m11, m21))
var m3, m4 map[Desc]int
fmt.Println("DeepEqual(m3,m4): ", reflect.DeepEqual(m3, m4))
var m31, m41 map[*Desc]int
fmt.Println("DeepEqual(m31,m41): ", reflect.DeepEqual(m31, m41))
var m32, m42 map[Desc]Desc
fmt.Println("DeepEqual(m32,m42): ", reflect.DeepEqual(m32, m42))
var m33, m43 map[Desc]*Desc
fmt.Println("DeepEqual(m33,m43): ", reflect.DeepEqual(m33, m43))
var m34, m44 map[*Desc]Desc
fmt.Println("DeepEqual(m34,m44): ", reflect.DeepEqual(m34, m44))
var m35, m45 map[*Desc]*Desc
fmt.Println("DeepEqual(m35,m45): ", reflect.DeepEqual(m35, m45))
m1, m2 = make(map[string]int), make(map[string]int)
m1[""], m2[""] = 1, 1
fmt.Println("DeepEqual(m1,m2): ", reflect.DeepEqual(m1, m2))
a := 1
m11, m21 = make(map[string]*int), make(map[string]*int)
m11[""], m21[""] = &a, &a
fmt.Println("DeepEqual(m11,m21): ", reflect.DeepEqual(m11, m21))
m3, m4 = make(map[Desc]int), make(map[Desc]int)
m3[Desc{}],m4[Desc{}] = 1,1
fmt.Println("DeepEqual(m3,m4): ", reflect.DeepEqual(m3, m4))
m31, m41 = make(map[*Desc]int), make(map[*Desc]int)
m31[&Desc{}],m41[&Desc{}] = 1,1
fmt.Println("DeepEqual(m31,m41): ", reflect.DeepEqual(m31, m41))
m32, m42 = make(map[Desc]Desc), make(map[Desc]Desc)
m32[Desc{}],m42[Desc{}] = Desc{},Desc{}
fmt.Println("DeepEqual(m32,m42): ", reflect.DeepEqual(m32, m42))
m33, m43 = make(map[Desc]*Desc), make(map[Desc]*Desc)
m33[Desc{}],m43[Desc{}] = &Desc{},&Desc{}
fmt.Println("DeepEqual(m33,m43): ", reflect.DeepEqual(m33, m43))
m34, m44 = make(map[*Desc]Desc), make(map[*Desc]Desc)
m34[&Desc{}],m44[&Desc{}] = Desc{},Desc{}
fmt.Println("DeepEqual(m34,m44): ", reflect.DeepEqual(m34, m44))
m35, m45 = make(map[*Desc]*Desc), make(map[*Desc]*Desc)
m35[&Desc{}],m45[&Desc{}] = &Desc{},&Desc{}
fmt.Println("DeepEqual(m35,m45): ", reflect.DeepEqual(m35, m45))
m31,m32,m41 = nil,nil,nil
fmt.Println("DeepEqual(m31,m32): ", reflect.DeepEqual(m31, m32)) // false m31 and m332k、v Different types , Although it is nil But the result is false
fmt.Println("DeepEqual(m31,m41): ", reflect.DeepEqual(m31, m41)) // true m31, m41 k、v The type is the same, so true
b := 1
m11["A"],m21["A"] = &a, &b
fmt.Println("DeepEqual(m11,m21): ", reflect.DeepEqual(m11, m21)) // true
m11["B"] = &a
fmt.Println("DeepEqual(m11,m21): ", reflect.DeepEqual(m11, m21)) // true The length is not equal , by false
}
Important summary
Two map You can't == Compare :Invalid operation: m1 == m2 (the operator == is not defined on map[string]int)
Various types of empty map:
1, Two k、v Empty of the same type map The depth comparison result is true
2, Two k、v Non empty of the same type map Depth comparison , Equal in length and corresponding to kv Equal depth , The result is true
3, Once the length is not equal , The depth comparison result is false
Array 、 section
Typical code
func CompareArrayAndSlice() {
var a1, a2 []int
fmt.Printf("&a1=%p, &a2=%p\n", &a1, &a2) //&a1=0xc000004078, &a2=0xc000004090
//fmt.Println("a1==a2: ", a2 == a1) // Slices can't be compared directly Invalid operation: a2 == a1 (the operator == is not defined on []int)
var a3, a4 [2]int
fmt.Println("a3==a4: ", a3 == a4) // true
fmt.Printf("&a3=%p, &a4=%p\n", &a3, &a4) // &a3=0xc00000a0d0, &a4=0xc00000a0e0
fmt.Println("a3==a4: ", a3 == a4) // true
a5, a6 := [2]int{1, 2}, [2]int{1, 2}
fmt.Println("a5==a6: ", a5 == a6) // true
fmt.Printf("&a5=%p, &a6=%p\n", &a5, &a6) // &a5=0xc00000a0f0, &a6=0xc00000a100
fmt.Println("a5==a6: ", a5 == a6) // true
a51, a61 := [2]int{1, 0}, [2]int{1}
fmt.Println("a51: ", a51) // a51: [1 0]
fmt.Println("a61: ", a61) // a61: [1 0]
fmt.Println("a51==a61: ", a51 == a61) // true
fmt.Printf("&a51=%p, &a6=%p\n", &a51, &a61) // &a5=0xc00000a0f0, &a6=0xc00000a100
fmt.Println("a51==a61: ", a51 == a61) // true
a52, a62 := [2]int{1, 0}, [1]string{""}
fmt.Println("a52: ", a52) // a51: [1 0]
fmt.Println("a62: ", a62) // a61: [1 0]
//fmt.Println("a52==a62: ", a52 == a62) // Invalid operation: a52 == a62 (mismatched types [2]int and [1]string)
fmt.Printf("&a52=%p, &a62=%p\n", &a52, &a62) // &a5=0xc00000a0f0, &a6=0xc00000a100
//fmt.Println("a52==a62: ", a52 == a62) // Invalid operation: a52 == a62 (mismatched types [2]int and [1]string)
a7, a8 := []Desc{}, []Desc{}
//fmt.Println("a7==a8: ", a7 == a8) // Invalid operation: a7 == a8 (the operator == is not defined on []Desc)
fmt.Printf("&a7=%p, &a8=%p\n", &a7, &a8) // &a7=0xc0000040a8, &a8=0xc0000040c0
a71, a81 := &a7, &a8
fmt.Println("a71==a81: ", a71 == a81) // false
a9, a10 := []*Desc{}, []*Desc{}
fmt.Printf("&a9=%p, &a10=%p\n", &a9, &a10) // &a9=0xc0000040d8, &a10=0xc0000040f0
var a11, a12 []Desc
fmt.Printf("&a11=%p, &a12=%p\n", &a11, &a12) // &a11=0xc000004108, &a12=0xc000004120
var a13, a14 []*Desc
fmt.Printf("&a13=%p, &a14=%p\n", &a13, &a14) // &a13=0xc000004138, &a14=0xc000004150
}
Important summary
1, Arrays can be compared with arrays , Slices are not comparable to slices 、 Arrays and slices are not comparable
2, The same type 、 An array with the same elements == After the operation is true
3, Two slice pointers == The comparison is constant false
Depth comparison
func CompareArrayAndSliceDeepEqual() {
var a1, a2 []int
a10, a20 := &a1, &a2
fmt.Println("a10==a20: ", a10 == a20) // false
var a11, a21 [2]int
fmt.Println("DeepEqual(a1,a2): ", reflect.DeepEqual(a1, a2)) // true
fmt.Println("DeepEqual(a11,a21): ", reflect.DeepEqual(a11, a21)) // true
a3, a4, a5 := []int{1, 2}, []int{1, 2}, [2]int{1, 2}
//fmt.Println("a3==a4: ", a3 == a4) //
a6 := a3
a7 := a5
fmt.Println("DeepEqual(a3,a4): ", reflect.DeepEqual(a3, a4)) // true
fmt.Println("DeepEqual(a4,a5): ", reflect.DeepEqual(a5, a4)) // false
fmt.Println("DeepEqual(a3,a6): ", reflect.DeepEqual(a3, a6)) // true
fmt.Println("DeepEqual(a5,a7): ", reflect.DeepEqual(a5, a7)) // true
fmt.Println("DeepEqual(a6,a7): ", reflect.DeepEqual(a6, a7)) // false
a8, a9 := &a3, &a4
fmt.Println("a8==a9: ", a8 == a9) // false
if a8 == a9 {
fmt.Println("a8==a9")
} else {
fmt.Println("a8!=a9") // a8!=a9
}
fmt.Printf("&a8=%p, &a9=%p\n", &a8, &a9) // &a8=0xc0000d8020, &a9=0xc0000d8028
fmt.Println("DeepEqual(a8,a9): ", reflect.DeepEqual(a8, a9)) // true since a8!=a9, Why is the depth equal here
a3, a4 = nil, nil
a8, a9 = nil, nil
//fmt.Println("a3==a4: ", a3 == a4) // Even if it is changed to Nil, But the compiler still does not allow Invalid operation: a3 == a4 (the operator == is not defined on []int)
fmt.Println("a3.type=", reflect.TypeOf(a3)) // []int
fmt.Println("a8.type=", reflect.TypeOf(a8)) // *[]int
fmt.Println("a8==a9: ", a8 == a9) // true
fmt.Println("DeepEqual(a3,a4): ", reflect.DeepEqual(a3, a4)) // true
fmt.Println("DeepEqual(a8,a9): ", reflect.DeepEqual(a8, a9)) // true
}
Important summary
For arrays :
1, When two arrays are empty, the depth is equal
2, The same type 、 Elements at the same index are equal , Then the depth is equal
For slices :
1, When two slices are empty, the depth is equal
2, The same type 、 Elements at the same index are equal , Then the depth is equal
3, Two slice pointers == The comparison is constant false
For pointer variables , If the slices pointed to by both are of the same type 、 Elements at the same index are equal , Then the depth is equal
Slice and array depth are not equal
func
Typical cases
func CompareFunc() {
f1 := func() {}
f2 := func() {}
//f3 := nil // Cannot assign nil without the explicit type
//f4 := nil // Cannot use 'nil' as the type Type
fmt.Printf("&f1=%p, &f2=%p\n", &f1, &f2)
//fmt.Println("f1==f2: ", f1 == f2) // Invalid operation: f1 == f2 (the operator == is not defined on func())
//fmt.Println("f3==f4: ", f3 == f4)
fmt.Println("DeepEqual(f1,f2): ", reflect.DeepEqual(f1, f2))
//f1, f2 = nil, nil
f1 = nil
fmt.Println("type f1=", reflect.TypeOf(f1)) // func()
//fmt.Println("f1==f2: ", f1 == f2) // Although assigned to nil, But there is no comparison , Because the type is still func() Direct comparison is not allowed
f5 := func() error { return nil }
fmt.Println("DeepEqual(f1,f2): ", reflect.DeepEqual(f1, f2)) // be based on DeepEqual Make a deep judgment , At this time, both are nil And the types are func(), Therefore true
fmt.Println("DeepEqual(f5,f1): ", reflect.DeepEqual(f5, f1)) // The two function types are different , Therefore false
f5 = nil
fmt.Println("type f5=", reflect.TypeOf(f5)) // type f5= func() error
fmt.Println("DeepEqual(f5,f1): ", reflect.DeepEqual(f5, f1)) // false At this time, both are nil, But it's func Different types , The depth judgment is false
f6 := func() error {
a := 0
_ = a
return nil
}
f7 := func() error { return nil }
f8 := func() error { return nil }
fmt.Println("type f6=", reflect.TypeOf(f6)) // type f6= func() error
fmt.Println("DeepEqual(f7,f6): ", reflect.DeepEqual(f7, f6)) // false
fmt.Println("DeepEqual(f7,f8): ", reflect.DeepEqual(f7, f8)) // false
fmt.Printf("&f6=%p\n", &f6)
fmt.Printf("&f7=%p\n", &f7)
fmt.Printf("&f8=%p\n", &f8)
fmt.Println("DeepEqual(f7,f6): ", reflect.DeepEqual(f7, f6)) // false fmt.Printf It does not affect the depth judgment results
fmt.Println("DeepEqual(f7,f8): ", reflect.DeepEqual(f7, f8)) // false
f7 = nil // Change to nil
f8 = nil
fmt.Println("DeepEqual(f7,f8): ", reflect.DeepEqual(f7, f8)) // true Only two are nil Time is equal to depth
}
Important summary
1, Two func Can't be used directly == Judge , Whether the function signature is the same or not , The compilation phase cannot pass ;
2,func To be an assignment nil It is still the original function type , At this time, I still can't talk to another func Compare ;
3, The two one. func Can be based on DeepEqual Make a deep judgment , Only both are for nil The judgment result is true. Other cases are false, Whether the signatures are the same or not .
Only two are nil Time is equal to depth
Basic types
Typical code
func CompareBasic() {
a1 := 1
a2 := 1
//fmt.Printf("&a1=%p, &b1=%p\n", &a1, &b1)
fmt.Println("a1==a2: ", a1 == a2) // true
a3 := &a1
a4 := &a2
a5 := a3 // a3、a5 All pointing 1 The memory where it is located
fmt.Println("a3==a4: ", a3 == a4) // false
fmt.Println("a3==a5: ", a3 == a5) // true
fmt.Println("*a3==*a4: ", *a3 == *a4) // true
fmt.Println("*a3==a1: ", *a3 == a1) // true
//fmt.Printf("a3: %p\n", &a3)
//fmt.Printf("a4: %p\n", &a4)
fmt.Println("a3==a4: ", a3 == a4) // false
fmt.Println("a3==a5: ", a3 == a5) // true
fmt.Println("*a3==*a4: ", *a3 == *a4) // true
fmt.Println("*a3==a1: ", *a3 == a1) // true
a6, a7 := "hello", "hello"
fmt.Printf("&a6=%p, &b7=%p\n", &a6, &a7)
fmt.Println("a6==a7: ", a6 == a7)
//fmt.Println("a6==a1: ", a6 == a1) // Invalid operation: a6 == a1 (mismatched types string and int)
}
Important summary
For basic types :
Variable comparison compilation of different types will not pass , Such as :Invalid operation: a6 == a1 (mismatched types string and int)
The same type 、 Variable with the same value ,== The operation structure is true
Two pointer variables , If the addresses pointed to are the same , be == The result is true
Depth comparison of basic types and == The result is the same
The basic type is aliased
func CompareBasicAlias() {
type T1 int
type T2 int
type T3 int64
type T4 int64
a1 := 1 // int
fmt.Println(reflect.TypeOf(a1))
//var a2 int8 = 1
//var a3 uint8 = 1
var a4 T1 = 1
//var a5 T2 = 1
var a6 T3 = 1
//var a7 T4 = 1
//fmt.Println("a1==a2: ", a1 == a2) // Invalid operation: a1 == a2 (mismatched types int and int8)
//fmt.Println("a1==a4: ", a1 == a4) // Although the bottom is Int type , but a4 Is from the alias , The compiler thinks that their types are different, so the compilation cannot pass , Cannot compare Invalid operation: a1 == a4 (mismatched types int and T1)
fmt.Println("a1==a4: ", T1(a1) == a4) // Convert one of them to the same type , Comparable , As long as the values are the same == The result is true
//fmt.Println("a2==a3: ", a2 == a3) // Invalid operation: a2 == a3 (mismatched types int8 and uint8)
//fmt.Println("a4==a5: ", a4 == a5) // Are variables defined by aliases , The direct type is different , Compile not pass , Cannot compare Invalid operation: a4 == a5 (mismatched types T1 and T2)
fmt.Println("int64(a4) == int64(a6): ", int64(a4) == int64(a6)) // true All converted to int64, If the values are the same, then == The result is true
}
struct
Typical code - empty struct
func CompareStruct() {
fmt.Println("---> start CompareDesc")
// Empty structure Always compare to true
d1 := Desc{}
d2 := Desc{}
d0 := d2
if d1 == d2 {
fmt.Println("if compare: d1 == d2")
}
fmt.Printf("&d1=%p, &d2=%p\n", &d1, &d2)
fmt.Printf("d1==d2: %v\n", d1 == d2) // true
fmt.Println("d1==d2: ", d1 == d2) // true
fmt.Println("d2==d0: ", d2 == d0) // true
// Empty structure 、 Pointer to the variable Don't use Printf when : The result of two variables with the same address is true、 The comparison result of two variables with different addresses is false;Printf When the applied variable contains two variables to be compared, the comparison result is true、Printf The effect on one of the two variables to be compared does not affect the comparison result
d3 := &Desc{}
d4 := &Desc{}
d5 := d4
if d3 == d4 {
fmt.Println("if compare: d3 == d4")
}
if d5 == d4 {
fmt.Println("if compare: d5 == d4")
}
fmt.Println("d3==d4: ", d3 == d4) // false
fmt.Println("d4==d5: ", d4 == d5) // true
//fmt.Printf("d3=%p, d4=%p\n", &d3, &d4) // Let go of this trip ,d3==d4 by true d4==d5 by true
//fmt.Printf("&d3=%p, &d4=%p\n", &d3, &d4) // Yes d3 and d4 All use fmt.Println, The result is true
fmt.Printf("d3=%p\n", &d3) // Yes d3 Use fmt.Println, Is still false
//fmt.Printf("d3==d4: %v\n", d3 == d4) // Use fmt.Printf To print d3==d4, Not separately d3、d4, The result is false
fmt.Println("d3==d4: ", d3 == d4) // false
fmt.Println("d4==d5: ", d4 == d5) // true
}
Important summary
For empty structures : Always compare to true
For empty structures 、 Pointer to the variable :
Don't use Printf when : The result of two variables with the same address is true、 The comparison result of two variables with different addresses is false;
Printf When the applied variable contains two variables to be compared, the comparison result is true、Printf The effect on one of the two variables to be compared does not affect the comparison result
Typical code - With attributes struct
func CompareStructWithAttr() {
fmt.Println("---> start CompareDescWithAttr")
// Structure with field 、 The default values for attributes are d1、d2== The result is... Anyway true
d1 := DescWithAttr{}
d2 := DescWithAttr{}
if d1 == d2 {
fmt.Println("if compare: d1 == d2")
}
fmt.Printf("d1=%p\n", &d1)
//fmt.Printf("&d1=%p, &d2=%p\n", &d1, &d2)
fmt.Printf("d1==d2: %v\n", d1 == d2) // true
fmt.Println("d1==d2: ", d1 == d2) // true
// Structure with field 、 The default values for attributes are 、 Pointer to the variable d3、d4== The result is... Anyway false
d3 := &DescWithAttr{}
//fmt.Printf("d3=%p\n", d3)
d4 := &DescWithAttr{}
if d3 == d4 {
fmt.Println("if compare: d3 == d4")
}
fmt.Printf("d3=%p\n", d3)
fmt.Printf("d4=%p\n", d4)
//fmt.Println("d3==d4: ", d3 == d4) // false
//fmt.Printf("&d3=%p, &d4=%p\n", &d3, &d4)
//fmt.Printf("d3=%p, d4=%p\n", d3, d4)
//fmt.Printf("d3==d4: %v\n", d3 == d4) // false
fmt.Println("d3==d4: ", d3 == d4) // false
// Structure with field 、 The same attribute is assigned the same value == The results are true
d5 := DescWithAttr{Name: "1"}
d6 := DescWithAttr{Name: "1"}
d7 := d6
fmt.Println("d5==d6: ", d5 == d6) // true
fmt.Println("d5==d7: ", d5 == d7) // true
fmt.Println("d6==d7: ", d6 == d7) // true
fmt.Printf("d5==d6: %v\n", d5 == d6) // true
fmt.Printf("d5=: %p\n", &d5)
fmt.Printf("d6=: %p\n", &d6)
fmt.Println("d7==d6: ", d7 == d6) // true
fmt.Println("d5==d6: ", d5 == d6) // true
fmt.Println("d5==d7: ", d5 == d7) // true
fmt.Println("d6==d7: ", d6 == d7) // true
// Structure with field 、 The same attribute is assigned the same value 、 Pointer to the variable == The result depends on the situation ,
d8 := &DescWithAttr{Name: "1"}
d9 := &DescWithAttr{Name: "1"}
d10 := d9
fmt.Println("d8==d9: ", d8 == d9) // false
fmt.Println("d8==d10: ", d8 == d10) // false
fmt.Println("d9==d10: ", d9 == d10) // true
fmt.Printf("d8=: %p\n", &d8)
fmt.Printf("d9=: %p\n", &d9)
fmt.Printf("d8==d9: %v\n", d8 == d9) // false
fmt.Printf("d9==d10: %v\n", d9 == d10) // true
fmt.Println("d8==d9: ", d8 == d9) // false
fmt.Println("d8==d10: ", d8 == d10) // false
fmt.Println("d9==d10: ", d9 == d10) // true
// The same attribute of the structure is assigned different values 、 Pointer to the variable == The result depends on the situation , Variables with two different addresses are always false, Two variables with the same address are always true
d11 := &DescWithAttr{Name: "1"}
d12 := &DescWithAttr{Name: "2"}
d13 := d12
fmt.Println("d11==d12: ", d11 == d12) // false
fmt.Println("d11==d13: ", d11 == d13) // false
fmt.Println("d12==d13: ", d12 == d13) // true
//fmt.Printf("d11==d12: %v\n", d11 == d12) // false
//fmt.Printf("d11==d13: %v\n", d11 == d13) // false
fmt.Printf("&d11=: %p\n", &d11)
fmt.Printf("d12=: %p\n", d12)
fmt.Printf("d13=: %p\n", d13)
fmt.Printf("&d12=: %p\n", &d12)
fmt.Printf("&d13=: %p\n", &d13)
fmt.Println("d11==d12: ", d11 == d12) // false
fmt.Println("d11==d13: ", d11 == d13) // false
fmt.Println("d12==d13: ", d12 == d13) // true
}
Important summary
1, Structure with field 、 The default values for attributes are : == The result is... Anyway true
2, Structure with field 、 The default values for attributes are 、 Pointer to the variable : == The result is... Anyway false
3, Structure with field 、 The same attribute is assigned the same value : == The results are true
4, Structure with field 、 The same attribute is assigned the same value 、 Pointer to the variable : Two structure objects that point to the same memory address == Judge equal , Otherwise it's not equal
5, The same attribute of the structure is assigned different values 、 Pointer to the variable == The result depends on the situation , Variables with two different addresses are always false, Two variables with the same address are always true
fmt.Printf It does not affect the comparison results
struct- Depth judgment
func CompareStructDeepEqual() {
fmt.Println("---> start CompareStructDeepEqual")
// Empty structure
d1 := Desc{}
d2 := Desc{}
d0 := d2
if d1 == d2 {
fmt.Println("if compare: d1 == d2") // yes
}
//fmt.Printf("&d1=%p, &d2=%p, &d0=%p\n", &d1, &d2, &d0) // &d1=0xc62e00, &d2=0xc62e00, &d0=0xc62e00
fmt.Println("DeepEqual(d1,d2): ", reflect.DeepEqual(d1, d2)) // true
fmt.Println("DeepEqual(d0,d1): ", reflect.DeepEqual(d1, d0)) // true
fmt.Println("DeepEqual(&d1,&d2): ", reflect.DeepEqual(&d1, &d2)) // true
fmt.Println("DeepEqual(&d0,&d1): ", reflect.DeepEqual(&d1, &d0)) // true
// Empty structure 、 Pointer to the variable Don't use Printf when : The result of two variables with the same address is true、 The comparison result of two variables with different addresses is false;Printf When the applied variable contains two variables to be compared, the comparison result is true、Printf The effect on one of the two variables to be compared does not affect the comparison result
d3 := &Desc{}
d4 := &Desc{}
d5 := d4
if d3 == d4 {
fmt.Println("if compare: d3 == d4") // yes
}
if d5 == d4 {
fmt.Println("if compare: d5 == d4") // yes
}
//fmt.Printf("d3=%p, d4=%p, d5=%p\n", d3, d4, d5) // d3=0xc62e00, d4=0xc62e00, d5=0xc62e00 Three new objects , But the addresses of the three objects above are the same
fmt.Println("DeepEqual(d3,d4): ", reflect.DeepEqual(d3, d4)) // true
fmt.Println("DeepEqual(d3,d5): ", reflect.DeepEqual(d3, d5)) // true
fmt.Println("DeepEqual(&d3,&d4): ", reflect.DeepEqual(&d3, &d4)) // true
fmt.Println("DeepEqual(&d3,&d5): ", reflect.DeepEqual(&d3, &d5)) // true
d3, d5 = nil, nil
//fmt.Printf("&d3=%p, &d4=%p, &d5=%p\n", &d3, &d4, &d5) // &d3=0xc000006030, &d4=0xc000006038, &d5=0xc000006040
fmt.Println("DeepEqual(d3,d4): ", reflect.DeepEqual(d3, d4)) // false
fmt.Println("DeepEqual(d3,d5): ", reflect.DeepEqual(d3, d5)) // true
fmt.Println("DeepEqual(&d3,&d4): ", reflect.DeepEqual(&d3, &d4)) // false
fmt.Println("DeepEqual(&d3,&d5): ", reflect.DeepEqual(&d3, &d5)) // true
}
Important summary
1, Empty structure :
The depth judgment of two empty structure objects is equal , Are all true
2, Empty structure 、 Pointer to the variable :
The depth judgment of the null structure object of two pointer types is equal , Are all true
3, Empty structure 、 Pointer variable and change to nil:
Pointer to the variable And It is amended as follows nil Pointer variable for , The result is false
It is amended as follows nil Pointer variable for And It is amended as follows nil Pointer variable for , The result is true
边栏推荐
- Kubernetes cluster construction of multiple ECS
- #24class静态成员
- 【opencv450-samples】读取图像路径列表并保持比例显示
- C. Planar Reflections-CodeCraft-21 and Codeforces Round #711 (Div. 2)
- 【opencv450-samples】inpaint 使用区域邻域恢复图像中的选定区域
- Svn icon disappearing solution
- Fegin client entry test
- Windows redis installation and simple use
- Ad20 learning notes I
- hiberate实体类CURD、事务操作汇总
猜你喜欢
QComboBox下拉菜单中有分隔符Separator时的样式设置
Pointer strengthening and improvement
24class static member
UE4 学习记录二 给角色添加骨架,皮肤,及运动动画
UE4 学习记录一 创建角色,并控制其移动
Problem recording and thinking
二进制、16进制、大端小端
Ble Low Power Bluetooth networking process and Bluetooth role introduction
Why is BeanUtils not recommended?
做接口测试,这3种工具到底什么时候用?
随机推荐
Sword finger offer 46 Translate numbers to strings (DP)
Idea auto generator generates constructor get/set methods, etc
二进制、16进制、大端小端
OBS-Studio-27.2.4-Full-Installer-x64.exe 下载
Leaky API interface practical development series (13): gooseneck cloud service php-api two-dimensional array parameter transfer solution
C. Yet Another Card Deck-Educational Codeforces Round 107 (Rated for Div. 2)
C1. k-LCM (easy version)-Codeforces Round #708 (Div. 2)
MySQL queries data by day, week, month, quarter and year
Determine whether the appointment time has expired
我的vscode
软件测试面试一直挂,面试官总是说逻辑思维混乱,怎么办?
What is CDN acceleration
jdbc常见异常及错误解决办法汇总
【opencv450 samples】创建图像列表yaml
Day3 data types and operators summary and job
A. Balance the Bits--Codeforces Round #712 (Div. 1)
go中全类型等值判断解析&综合汇总
问题记录与思考
【2023校招刷题】番外篇1:度量科技FPGA岗(大致解析版)
CSDN add on page Jump and off page specified paragraph jump