欢迎光临散文网 会员登陆 & 注册

一个关于“2个GolangMap是否相等”引发的反射知识点

2022-08-29 10:43 作者:在哪都叫Ember  | 我要投稿

先附上今日Golang每日一题:如何确认两个 map 是否相等?

解答区大部分都是说把map内容先按key比对,然后marshal到有序json,用string做对比

再往下看看,有老哥说可以直接用反射做比对

package main

import(    "fmt"

           "relflect")

func main() {    
    var m map[string]int

   var n map[string]int

   fmt.Println(reflect.DeepEqual(m,n))

}


下面就让我们看下反射到底能不能实现这一目标

直接上测试代码:

    

func TestEqual(t *testing.T) {

    x := make(map[string]int)

    x["test1"] = 1

    x["test2"] = 2

    m := x


    y := make(map[string]int)

    y["test1"] = 1

    y["test2"] = 2

    n := y

    fmt.Println(reflect.DeepEqual(m, n))    //true

    n["test1"] = 3

    fmt.Println(reflect.DeepEqual(m, n))    //false

    n["test1"] = 1

    n["test3"] = 3

    fmt.Println(reflect.DeepEqual(m, n))    //false

}

通过测试数据可以看到,是可以解决上述问题的


那么,该接口是怎么得到这个结果的呢?

首先是外部接口 DeepEqual的实现:

    第一步,判断是否为nil,这步比较简单,我就不贴出来了

    第二步,运用Value和Type判断是否是同类型数据

             v1 := ValueOf(x)

             v2 := ValueOf(y)

            下面这句其实在第三步里有过调用,我感觉是多余的,或许是为了逻辑清晰吧

             if v1.Type() != v2.Type() {    return false    }

    第三步,是封装的私有函数调用,deepValueEqual(v1, v2, make(map[visit]bool))

            如果只以咱们这道题的map[string]int 为例的话:

             deepValueEqual的调用顺序如下:

                    v1,v2是否有效

                    v1,v2类型是否相同

                    switch(v1.Kind()){

                            case Map:

                                    range  v1.MapKeys()

                                    val1,val2 是map里相同key的值,                                                                                              if !deepValueEqual(val1,val2,visited) return false

                    }

看到这里,想必你也明白了,其实这里没什么玄乎的地方,解决方法跟咱们通常想到的map range比对法一模一样,只是人家的函数更严谨,更底层,更抽象



一个关于“2个GolangMap是否相等”引发的反射知识点的评论 (共 条)

分享到微博请遵守国家法律