博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【玩转Golang】reflect.DeepEqual
阅读量:6873 次
发布时间:2019-06-26

本文共 3217 字,大约阅读时间需要 10 分钟。

如果有两个map,内容都一样,只有顺序不同

m1:=map[string]int{
"a":1,"b":2,"c":3};m2:=map[string]int{
"a":1,"c":3,"b":2};

我们怎么判断二者是否一致呢?

如果你打算这么写:

fmt.Println("m1==m2",m1==m2)

这是行不通的,go没有重写map的==操作符,编译器会报告错误:

invalid operation: m1 == m2 (map can only be compared to nil)

意思是map的变量只能和空(nil)比较,例如:

fmt.Println("m1 == nil?",m1==nil)fmt.Println("m2 != nil?",m2!=nil)

这没有问题,执行结果是:

Running... m1 == nil? false m2 != nil? true

那怎么比较呢?如果要编程实现,还真是麻烦,比如我的想法是:循环m1,看看每个key是否都在m2中存在,再比较m1[key]是否和m2[key]相等,如果都ok,再依次循环m2。还真是麻烦:

func cmpMap(m1,m2  map[string]int)bool{    for k1,v1 :=range m1{        if v2,has:=m2[k1];has{            if v1!=v2 {                return false            }        }else{            return false;        }    }    for k2,v2:=range m2{        if v1,has:=m1[k2];has{            if v1!=v2{                return false;            }        }else{            return false;        }    }    return true;}

其实,go的反射包中有一个巨好用的武器reflect.DeepEqual,可以方便解决这个问题,请看:

package mainimport(    "fmt"        "reflect")type tt struct{    Code int}func main(){    m1:=map[string]int{
"a":1,"b":2,"c":3}; m2:=map[string]int{
"a":1,"c":3,"b":2}; fmt.Println("m1 == nil?",m1==nil) fmt.Println("m2 != nil?",m2!=nil) //fmt.Println("m1==m2",m1==m2) fmt.Println("cmpMap(m1,m2) = ",cmpMap(m1,m2)); fmt.Println("reflect.DeepEqual(m1,m2) = ",reflect.DeepEqual(m1,m2)) fmt.Println() m3:=map[string]int{
"a":1,"b":2,"c":3,"d":1}; fmt.Println("cmpMap(m1,m3)=",cmpMap(m1,m3)); fmt.Println("reflect.DeepEqual(m1,m3) = ",reflect.DeepEqual(m1,m3))}func cmpMap(m1,m2 map[string]int)bool{ for k1,v1 :=range m1{ if v2,has:=m2[k1];has{ if v1!=v2 { return false } }else{ return false; } } for k2,v2:=range m2{ if v1,has:=m1[k2];has{ if v1!=v2{ return false; } }else{ return false; } } return true;}

执行结果:

Running...m1 == nil? falsem2 != nil? truecmpMap(m1,m2) =  truereflect.DeepEqual(m1,m2) =  truecmpMap(m1,m3)= falsereflect.DeepEqual(m1,m3) =  falseSuccess: process exited with code 0.

但是美中不足的是,由于reflect.DeepEqual需要经过反射操作,效率比我们自己写的函数差的多了,写个简单的测试:

start:=time.Now();	for i:=0;i<100000;i++{		cmpMap(m1,m2)	}	end:=time.Now();	du:=end.Sub(start)	fmt.Println("100000 call cmpMap(m1,m2) elapsed=",du)	start=time.Now();	for i:=0;i<100000;i++{		reflect.DeepEqual(m1,m2);	}	end=time.Now();	du=end.Sub(start);	fmt.Println("100000 call reflect.DeepEqual(m1,m2) elapsed=",du)

 看看结果,大约有10倍的差距

100000 call cmpMap(m1,m2) elapsed= 75.544992ms100000 call reflect.DeepEqual(m1,m2) elapsed= 735.577069ms

当然,在一般情况下,这点儿性能损失不算什么,尤其在不确定类型需要反射的时候,更是我们不可不用的强大工具。

比如:

func main(){    m1:=map[string]interface{}{
"a":"1", "b":2, "c":3}; m2:=map[string]interface{}{
"a":1, "c":"3", "b":2}; fmt.Println(`reflect.DeepEqual(m1["a"],m2["a"]`,reflect.DeepEqual(m1["a"],m2["a"])); fmt.Println(`reflect.DeepEqual(m1["b"],m2["b"]`,reflect.DeepEqual(m1["b"],m2["b"]));}

执行结果:

Running...reflect.DeepEqual(m1["a"],m2["a"] falsereflect.DeepEqual(m1["b"],m2["b"] true

这种情况,如果我们自己写代码比较,势必要使用switch type语法,实在是太麻烦了,感谢go包含了这么好的工具。

 

转载于:https://www.cnblogs.com/dajianshi/p/4220332.html

你可能感兴趣的文章
CentOS 6.5 自动安装镜像
查看>>
Storm与Spark Streaming比较
查看>>
我的友情链接
查看>>
Exchange Server 运维管理01:Exchange中Active Directory 有什么用?
查看>>
linux系统管理之四:服务状态
查看>>
VMware View FAQ[一]
查看>>
【原创翻译】布尔值(boolean)
查看>>
三元运算式、lambda表达式、内置函数map、reduce、filter以及yield生成器
查看>>
MySQL分库分表分表后数据的查询(5th)
查看>>
iOS-点击图片放大,再次点击返回原视图 类似查看相册的功能
查看>>
JAVA -- stateless4j StateMachine 使用浅析(二)
查看>>
oracle checkpoint
查看>>
KVM虚拟化开源高可用方案(六)ISCSI ON DRBD搭建及常见故障处理
查看>>
android device related
查看>>
iOS 6 Beta3即将发布,iPhone面板谍照已经曝光
查看>>
hadoop 源码包编译
查看>>
关于scrapy的piplines
查看>>
Windows Server 2008 FTP用户目录隔离模式
查看>>
python实现linux下指定目录下文件中的单词个数统计
查看>>
Android源代码下载编译
查看>>