当前位置:首页 > 科技  > 软件

GO 比较两个对象是否相同

来源: 责编: 时间:2023-10-06 19:19:47 180观看
导读本文主要是来聊一聊关于 Golang 中的深度比较 DeepEqual因为最近发现身边的小伙伴写 2 个或者多个 map 比较的时候,都是自己去实现去比较每一个结构,每一个节点的 key 和 value 是不是都相等,且根据不同的数据结构,都要去

本文主要是来聊一聊关于 Golang 中的深度比较 DeepEqualkYy28资讯网——每日最新资讯28at.com

因为最近发现身边的小伙伴写 2 个或者多个 map 比较的时候,都是自己去实现去比较每一个结构,每一个节点的 key 和 value 是不是都相等,且根据不同的数据结构,都要去实现一遍,没有必要自己造轮子kYy28资讯网——每日最新资讯28at.com

我们知道,对于布尔类型,整形的,浮点类型,复数,指针,字符串类型的值可以直接使用 == 来进行比较,确认双方是否相等kYy28资讯网——每日最新资讯28at.com

甚至对于 channel 类型,也是可以使用 == 来进行比较是否相等的kYy28资讯网——每日最新资讯28at.com

那么对于 golang 中的 切片 slice,数组 array,map,interface{},struct 结构体我们如何去进行比较呢?显然使用 == 是不行的,此处的 m1 和 m2 是 map[string]intkYy28资讯网——每日最新资讯28at.com

图片图片kYy28资讯网——每日最新资讯28at.com

此处你是否可能会想到 C++ 还可以去重载操作符,咱们实现一下对应数据类型的操作符就可以了,妥妥的kYy28资讯网——每日最新资讯28at.com

你是否还会想到 PHP 中的 === 可以直接去比较数据的值和数据的类型,称为全等比较运算符kYy28资讯网——每日最新资讯28at.com

那么,看到此处,是否可以猜测 golang 的做法也是类似的呢?kYy28资讯网——每日最新资讯28at.com

实际上 golang 去比较两个对象是否相同,也是通过去比较数据的类型,数据的值,数据的长度等等维度来进行确认的kYy28资讯网——每日最新资讯28at.com

C++ 是需要我们自己编码实现,PHP 是直接提供 === ,Golang 是给我们在反射包中提供一个 DeepEqual 函数来进行灵活使用kYy28资讯网——每日最新资讯28at.com

DeepEqual 案例

图片图片kYy28资讯网——每日最新资讯28at.com

func DeepEqual(x, y interface{}) bool

很多朋友在不知道 golang 有提供 DeepEqual 功能的时候,比较 2 个 map 可能会这样去实现:kYy28资讯网——每日最新资讯28at.com

func mapEqual(m1, m2 map[string]int) bool {   for k, v := range m1 {      vv, ok := m2[k]      if !ok {         return false      }      if v != vv {         return false      }   }   return true}

当然也没有啥问题,但是如果这个时候需要我们比较两个切片是否相等,两个结构体是否相等,甚至两个 interface{} 是否相等的时候,是不是都要去写对应的工具函数呢?kYy28资讯网——每日最新资讯28at.com

使用 DeepEqual 比较 map

图片图片kYy28资讯网——每日最新资讯28at.com

两个同一类型的 map,使用自己编写的 mapEqual 和 使用 DeepEqual 我们得到的结果都是我们所期望的kYy28资讯网——每日最新资讯28at.com

但是对于 DeepEqual 来说,你可以传入任何类型的数据,入参是 2 个 interface{} 类型的数据,响应是 boolkYy28资讯网——每日最新资讯28at.com

对于 mapEqual 来说,你就只能传入 map[string]int 类型的数据,看到此处,自己造轮子,弊端还是很明显的吧kYy28资讯网——每日最新资讯28at.com

自然,你也可以去将参数设计成 interface{} 类型的,然后再去进行各种反射处理kYy28资讯网——每日最新资讯28at.com

可是明明有官方库,何必自己再弄一遍呢,我们不应该是吸收官方的思想和精华,站在巨佬的肩膀上去做更多有意义的事情吗kYy28资讯网——每日最新资讯28at.com

使用 DeepEqual 比较 map 和 自定义类型

可使用 DeepEqual 的时候,一定要知道他的运作机制和原理kYy28资讯网——每日最新资讯28at.com

例如下面的案例,我们自定义一个数据类型 myType,实际上和 map[string]int 是一样的, 可是我们去将原生的 map[string]int 的 m1 和 myType 类型 m2 进行比较的时候,他们实际上是不相等的kYy28资讯网——每日最新资讯28at.com

图片图片kYy28资讯网——每日最新资讯28at.com

那么,看到这里,实际上 DeepEqual 自然是要比我们自己写的 mapEqual 强太多了,他不仅关注数据的值,还会关注具体数据的类型,根据不同的数据类型,来进行不同的数据校验和比较kYy28资讯网——每日最新资讯28at.com

DeepEqual 原理

DeepEqual 的代码实现也非常简单,参数中传入 interface{}, 实现上会去确认具体的数据类型,是否为空,如果是一般的的数据类型,那么直接使用 == 进行比较即可kYy28资讯网——每日最新资讯28at.com

如果是其他的数据类型,那么就会递归的去调用 deepValueEqual 来一层一层的去校验数据和比较kYy28资讯网——每日最新资讯28at.com

为什么需要递归调用呢?kYy28资讯网——每日最新资讯28at.com

这个很明显,例如对于一个切片来说,如果里面的元素是简单的字符串,或者整型数字,那么第一层使用 deepValueEqual 去识别和处理切片的类型比较,读取到切片元素的时候就可以直接走 == 来确认是否相等kYy28资讯网——每日最新资讯28at.com

那么切片中也是可以是其他的任意数据结构的,也可以是自定义的结构体kYy28资讯网——每日最新资讯28at.com

因此在做这种比较的时候,遍历到切片元素的时候,也要去确认元素是什么类型的,如果是上述提到的非简单类型,那么仍然需要继续一层一层的识别他的类型,和他的值,再进行逐个比较kYy28资讯网——每日最新资讯28at.com

例如这样去比较这样结构的切片,真的完全有必要递归去一层一层的确认数据类型和数值type Node struct{   M map[string]int   In interface{}   Sli []map[int][chan int]}var sli = []Node{...}

在比较的过程中,哪怕有一个环节不是我们所期望的,那么都会直接返回 false,即不相等kYy28资讯网——每日最新资讯28at.com

图片图片kYy28资讯网——每日最新资讯28at.com

那么,仔细看 DeepEqual 的注释,我们可以看到,这里有详细的关于各种数据类型的比较和校验细节,翻译一下仅供大家参考,希望你有机会用到kYy28资讯网——每日最新资讯28at.com

  • 数组 Array

比较相同索引处的元素是否相等kYy28资讯网——每日最新资讯28at.com

  • 结构体 struct

比较相应字段,包括导出和不导出(此处表示字段开头是大写还是小写)kYy28资讯网——每日最新资讯28at.com

  • 函数 Func

只有当函数为 nil 的时候,才会是相等的,其他情况都不相等kYy28资讯网——每日最新资讯28at.com

  • Interface{}

两者都存在具体的值的时候,那么是相等的kYy28资讯网——每日最新资讯28at.com

  • Map

都为空的时候是可以是相等的kYy28资讯网——每日最新资讯28at.com

都不为空的时候,会去比较他们的长度,他们是否有相同的 key 且对应相同的 value ,若都相同,则相等kYy28资讯网——每日最新资讯28at.com

  • 指针 pointer

可以直接使用 == 进行比较,和 == 效果一致,或者指针指向的值是相等的kYy28资讯网——每日最新资讯28at.com

  • 切片 slice

都为 nil 的时候,是相等的kYy28资讯网——每日最新资讯28at.com

不为空的时候,会去比较他们的长度,且指向的底层数组也得有相同的元素,也就是指向底层数组的地址是相同的kYy28资讯网——每日最新资讯28at.com

  • 对于 other values 其他的数据类型,例如整型,布尔,字符串,通道

直接可以使用 == 来进行比较, DeepEqual 的源码实现对于这些类型的数据也是直接使用 == 比较的,简单粗暴kYy28资讯网——每日最新资讯28at.com

总结

本次主要聊了关于kYy28资讯网——每日最新资讯28at.com

  • 非简单数据类型的比较如何去处理
  • DeepEqual 的使用方式以及注意事项
  • DeepEqual 的原理和其支持的数据类型的判定规则

本文链接://www.dmpip.com//www.dmpip.com/showinfo-26-12137-0.htmlGO 比较两个对象是否相同

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 计数排序(Counting Sort)详解

下一篇: 十个事半功倍的IntelliJ Idea插件和主题

标签:
  • 热门焦点
  • 对标苹果的灵动岛 华为带来实况窗功能

    对标苹果的灵动岛 华为带来实况窗功能

    继苹果的灵动岛之后,华为也在今天正式推出了“实况窗”功能。据今天鸿蒙OS 4.0的现场演示显示,华为的实况窗可以更高效的展现出实时通知,比如锁屏上就能看到外卖、打车、银行
  • 天猫精灵Sound Pro体验:智能音箱没有音质?来听听我的

    天猫精灵Sound Pro体验:智能音箱没有音质?来听听我的

    这几年除了手机作为智能生活终端最主要的核心之外,第二个可以成为中心点的产品是什么?——是智能音箱。 手机在执行命令的时候有两种操作方式,手和智能语音助手,而智能音箱只
  • 6月iOS设备好评榜:第一蝉联榜首近一年

    6月iOS设备好评榜:第一蝉联榜首近一年

    作为安兔兔各种榜单里变化最小的那个,2023年6月的iOS好评榜和上个月相比没有任何排名上的变化,仅仅是部分设备好评率的下降,长年累月的用户评价和逐渐退出市场的老款机器让这
  • 印度登月最关键一步!月船三号今晚进入环月轨道

    印度登月最关键一步!月船三号今晚进入环月轨道

    8月5日消息,据印度官方消息,月船三号将于北京时间今晚21时30分左右开始近月制动进入环月轨道。这是该探测器能够成功的最关键步骤之一,如果成功将开始围
  • 为什么你不应该使用Div作为可点击元素

    为什么你不应该使用Div作为可点击元素

    按钮是为任何网络应用程序提供交互性的最常见方式。但我们经常倾向于使用其他HTML元素,如 div span 等作为 clickable 元素。但通过这样做,我们错过了许多内置浏览器的功能。
  • 雅柏威士忌多款单品价格大跌,泥煤顶流也不香了?

    雅柏威士忌多款单品价格大跌,泥煤顶流也不香了?

    来源 | 烈酒商业观察编 | 肖海林今年以来,威士忌市场开始出现了降温迹象,越来越多不断暴涨的网红威士忌也开始悄然回归市场理性。近日,LVMH集团旗下苏格兰威士忌品牌雅柏(Ardbeg
  • “又被陈思诚骗了”

    “又被陈思诚骗了”

    作者|张思齐 出品|众面(ID:ZhongMian_ZM)如今的国产悬疑电影,成了陈思诚的天下。最近大爆电影《消失的她》票房突破30亿断层夺魁暑期档,陈思诚再度风头无两。你可以说陈思诚的
  • 微博大门常打开,迎接海外画师漂洋东渡

    微博大门常打开,迎接海外画师漂洋东渡

    作者:互联网那些事“起猛了,我能看得懂日语了”。“为什么日本人说话我能听懂?”“中文不像中文,日语不像日语,但是我竟然看懂了”…&hell
  • iQOO 11S屏幕细节公布:首发三星2K E6全感屏 安卓最好的直屏手机

    iQOO 11S屏幕细节公布:首发三星2K E6全感屏 安卓最好的直屏手机

    日前iQOO手机官方宣布,新一代电竞旗舰iQOO 11S将会在7月4日19:00正式与大家见面。随着发布时间的日益临近,官方关于该机的预热也更加密集,截至目前已
Top
Baidu
map