github.com/qiuhoude/go-web@v0.0.0-20220223060959-ab545e78f20d/prepare/20_trap/compareobj/main.go (about)

     1  package main
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/subtle"
     6  	"encoding/json"
     7  	"fmt"
     8  	"reflect"
     9  	"strings"
    10  )
    11  
    12  type data struct {
    13  	num     int
    14  	fp      float32
    15  	complex complex64
    16  	str     string
    17  	char    rune
    18  	yes     bool
    19  	events  <-chan string
    20  	handler interface{}
    21  	ref     *byte
    22  	raw     [10]byte
    23  }
    24  
    25  type data2 struct {
    26  	num    int               //ok
    27  	checks [10]func() bool   //not comparable
    28  	doit   func() bool       //not comparable
    29  	m      map[string]string //not comparable
    30  	bytes  []byte            //not comparable
    31  }
    32  
    33  func main() {
    34  	v1 := data{}
    35  	v2 := data{}
    36  	fmt.Println("v1 == v2:", v1 == v2) //prints: v1 == v2: true
    37  
    38  	// 使用reflect.DeepEqual 深入比较
    39  	var b1 []byte = nil
    40  	b2 := []byte{}
    41  	fmt.Println("reflect b1 == b2:", reflect.DeepEqual(b1, b2)) //prints: b1 == b2: false
    42  	// bytes.是对于slice nil 和 [] 是相等的
    43  	fmt.Println("bytes b1 == b2:", bytes.Equal(b1, b2)) // true
    44  
    45  	vv1 := data2{}
    46  	vv2 := data2{}
    47  	fmt.Println("vv1 == vv2:", reflect.DeepEqual(vv1, vv2))
    48  
    49  	m1 := map[string]string{"one": "a", "two": "b"}
    50  	m2 := map[string]string{"two": "b", "one": "a"}
    51  	fmt.Println("m1 == m2:", reflect.DeepEqual(m1, m2)) //prints: m1 == m2: true
    52  
    53  	s1 := []int{1, 2, 3}
    54  	s2 := []int{1, 2, 3}
    55  	fmt.Println("s1 == s2:", reflect.DeepEqual(s1, s2)) //prints: s1 == s2: true
    56  
    57  	// 字符串的比较
    58  	/*
    59  		如果你的byte slice中包含需要验证用户数据的隐私信息(比如,加密哈希、tokens等),
    60  		不要使用reflect.DeepEqual()、bytes.Equal(),或者bytes.Compare()
    61  		因为这些函数将会让你的应用易于被定时攻击 使用'crypto/subtle'包中的函数(即,subtle.ConstantTimeCompare())
    62  	*/
    63  	zhB := []byte("你好!老外")
    64  	zhS := "你好!老外" // 此处也可能不是utf8类型
    65  	fmt.Println("zhB == zhS", string(zhB) == zhS)
    66  	fmt.Println("zhB strings.EqualFold zhS", strings.EqualFold(string(zhB), zhS))
    67  	fmt.Println("zhB bytes.EqualFold zhS", bytes.EqualFold(zhB, []byte(zhS)))
    68  	fmt.Println("zhB subtle.ConstantTimeCompare zhS", subtle.ConstantTimeCompare(zhB, []byte(zhS)))
    69  
    70  	aa1 := []string{"one", "two"}
    71  	aa2 := []interface{}{"one", "two"}
    72  	fmt.Println("aa1 == aa2:", reflect.DeepEqual(aa1, aa2))
    73  
    74  	data := map[string]interface{}{
    75  		"code": 200,
    76  		//"value": []string{"one", "two"},
    77  	}
    78  	encoded, _ := json.Marshal(data)
    79  	var decoded map[string]interface{}
    80  	json.Unmarshal(encoded, &decoded)
    81  	fmt.Println("data == decoded:", reflect.DeepEqual(data, decoded))
    82  	fmt.Printf("encoded %v \n", reflect.TypeOf(decoded["code"]))
    83  
    84  }