当前位置: 首页 > news >正文

【golang】【源代码】reflect.DeepEqual(x,y)函数

reflect.DeepEqual(x, y)函数

功能是比较x和y是否一致,x和y不仅限于基础类型,也可以是像array、 slice、 map、 ptr、struct、interface类型,在代码中经常能见到。
一起看下是怎么实现的吧~

func DeepEqual(x, y interface{}) bool {if x == nil || y == nil {return x == y}v1 := ValueOf(x)v2 := ValueOf(y)if v1.Type() != v2.Type() {return false}return deepValueEqual(v1, v2, make(map[visit]bool), 0)
}
  1. 先判断x和y是否为空,一方为空,另一方不为空则肯定不相等;两者都为空那就相等。
  2. 判断类型是否一致,如果x和y类型都不一致,那肯定不相等。

继续比较,

func deepValueEqual(v1, v2 Value, visited map[visit]bool, depth int) bool {if !v1.IsValid() || !v2.IsValid() {return v1.IsValid() == v2.IsValid()}if v1.Type() != v2.Type() {return false}// if depth > 10 { panic("deepValueEqual") }	// for debugging// We want to avoid putting more in the visited map than we need to.// For any possible reference cycle that might be encountered,// hard(t) needs to return true for at least one of the types in the cycle.hard := func(k Kind) bool {switch k {case Map, Slice, Ptr, Interface:return true}return false}if v1.CanAddr() && v2.CanAddr() && hard(v1.Kind()) {addr1 := unsafe.Pointer(v1.UnsafeAddr())addr2 := unsafe.Pointer(v2.UnsafeAddr())if uintptr(addr1) > uintptr(addr2) {// Canonicalize order to reduce number of entries in visited.// Assumes non-moving garbage collector.addr1, addr2 = addr2, addr1}// Short circuit if references are already seen.typ := v1.Type()v := visit{addr1, addr2, typ}if visited[v] {return true}// Remember for later.visited[v] = true}switch v1.Kind() {case Array:for i := 0; i < v1.Len(); i++ {if !deepValueEqual(v1.Index(i), v2.Index(i), visited, depth+1) {return false}}return truecase Slice:if v1.IsNil() != v2.IsNil() {return false}if v1.Len() != v2.Len() {return false}if v1.Pointer() == v2.Pointer() {return true}for i := 0; i < v1.Len(); i++ {if !deepValueEqual(v1.Index(i), v2.Index(i), visited, depth+1) {return false}}return truecase Interface:if v1.IsNil() || v2.IsNil() {return v1.IsNil() == v2.IsNil()}return deepValueEqual(v1.Elem(), v2.Elem(), visited, depth+1)case Ptr:if v1.Pointer() == v2.Pointer() {return true}return deepValueEqual(v1.Elem(), v2.Elem(), visited, depth+1)case Struct:for i, n := 0, v1.NumField(); i < n; i++ {if !deepValueEqual(v1.Field(i), v2.Field(i), visited, depth+1) {return false}}return truecase Map:if v1.IsNil() != v2.IsNil() {return false}if v1.Len() != v2.Len() {return false}if v1.Pointer() == v2.Pointer() {return true}for _, k := range v1.MapKeys() {val1 := v1.MapIndex(k)val2 := v2.MapIndex(k)if !val1.IsValid() || !val2.IsValid() || !deepValueEqual(val1, val2, visited, depth+1) {return false}}return truecase Func:if v1.IsNil() && v2.IsNil() {return true}// Can't do better than this:return falsedefault:// Normal equality sufficesreturn valueInterface(v1, false) == valueInterface(v2, false)}
}
  1. 如果是slice map ptr interface 类型,hard 返回true; 如果是array 原始元素类型hard返回false。
  2. 拿slice类型举个例子,会先判断x和y是否为空,会判断x和y的长度是否一致,判断是否指向同一指针,然后递归比较各个元素。
  3. 注意&Person{name1,age1} 是ptr类型,Person{name1,age1}是struct类型。
  4. 注意如果是func类型,如果两个func都会nil时认为x和y一致,否则被判定为不一致。

大家可以用各种例子试一试,debug一下

http://www.lryc.cn/news/19006.html

相关文章:

  • Python实现定时执行脚本(4)
  • 量子力学(4) 全同粒子
  • 13、Swin Transformer: Hierarchical Vision Transformer using Shifted Windows
  • C++基础入门丨8. 结构体——还需要知道这些
  • 算法第十六期——动态规划(DP)之线性DP
  • 智慧新零售网络解决方案,助力新零售企业数智化转型
  • Go语言规范中的可赋值
  • 外盘国际期货招商:原油市场热点话题
  • [蓝桥杯 2018 省 A] 付账问题 贪心题
  • 微机原理复习(周五),计算机组成原理图
  • 用了10年Postman,意想不到它的Mock功能也如此强大
  • 项目重构,从零开始搭建一套新的后台管理系统
  • day20_Map
  • localStorage和sessionStorage
  • IP地址,子网掩码,网段 概念详解
  • 数影周报:动视暴雪疑似数据泄露,数据出境安全评估申报最新进展
  • Web安全最详细学习路线指南,从入门到入职(含书籍、工具包)
  • ChatGPT?听说Biying把它下架了
  • 中电金信:金融数字化转型路在何方?这里有答案
  • 【Leedcode】数据结构中链表必备的面试题(第五期)
  • ECDH secp256k1 集成
  • 工单模型的理解与应用
  • Python年利率计算器【N日年化收益率】
  • 3年测试拿8K,被校招来的实习生反超薪资,其实你在假装努力
  • 因子分析计算权重
  • 国家调控油价预测案例+源码
  • Gephi快速入门
  • GitHub
  • QT基础入门【调试篇】QT远程部署与调试嵌入式ARM开发板
  • 可观测性最佳实践|阿里云事件总线 EventBridge 最佳实践