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

十分钟掌握Go语言==运算符与reflect.DeepEqual函数处理interface{}值的比较规则

在 Go 语言中,interface{} 类型是一种特殊的接口类型,它表示任意类型的值。你可以使用 == 运算符来检测任意两个 interface{} 类型值的相等性,比较的规则和一般的接口类型一样,需要满足以下条件:

  • 两个 interface{} 值的动态类型必须相同,也就是说,它们存储的具体类型必须一致。
  • 两个 interface{} 值的动态值必须相等,也就是说,它们存储的具体值必须可以比较的。

根据 Go 语言规范的描述,interface{} 类型的值在内存中是由两个字(word)组成的,一个字存储了动态类型的信息,另一个字存储了动态值的信息。如果动态值的大小超过了一个字,那么这个字就存储了动态值的指针,指向实际的动态值。

Go 编译器是如何判定 interface{} 值是否相等的呢?

使用 == 符号比较两个 interface{} 类型的值时,Go编译器会先比较它们的动态类型,也就是比较它们的第一个字,看是否指向相同的类型信息。如果不相同直接返回 false,如果相同,则继续比较它们的动态值,也就是比较它们的第二个字,看是否相等。如果动态值的大小超过了一个字,那么这个字就是一个指针,需要根据指针找到实际的动态值,并且根据动态类型的规则进行比较。

例如,如果动态类型是数组,那么就需要逐个比较数组的元素,如果动态类型是结构体,那么就需要逐个比较结构体的字段,以此类推。

下面是一个简单的例子,演示了如何使用 == 符号比较两个 interface{} 类型的值:

package mainimport "fmt"func main() {var a, b interface{}// 给 a 赋值为 int64 类型的 1a = int64(1)// 给 b 赋值为 int64 类型的 2b = int64(2)// a和b的动态类型相同, 动态值不同, 输出结果为 falsefmt.Println(a == b) // false// 给 b 赋值为 int64 类型的 1b = int64(1)// a和b的动态类型相同, 动态值也相同, 此时输出结果为truefmt.Println(a == b) // true// 给 b 赋值为 float32 类型的 1b = float32(1)// 此时a和b的动态类型不相同, 就不会进行动态值的处理, 输出结果为falsefmt.Println(a == b) // false// 给 a,b 赋值为 int 类型的数组a = [5]int{1, 2, 3, 4, 5}b = [5]int{1, 2, 3, 4, 5}fmt.Println(a == b) // true// 给 b 赋值为 int 类型的数组b = [5]int{1, 2, 3, 4, 6}fmt.Println(a == b) // false// 给 b 赋值为 int 类型的切片b = []int{1, 2, 3, 4, 5}// 此时a和b的动态类型已然不相同, 就不会进行动态值的处理, 输出结果为falsefmt.Println(a == b) // false// 给 a 赋值为 int 类型的切片a = []int{1, 2, 3, 4, 5}// 此时a和b的动态类型和动态值虽然相同, 但是在Go语言中切片类型的值是不能用 == 符号比较,会引发运行时错误//fmt.Println(a == b) // panic: runtime error: comparing uncomparable type []int
}

== 运算符通常只能用于比较基本类型和支持 == 操作的复合类型,如数组、结构体等,而不能用于比较切片、映射、函数等类型,否则会引发编译错误或运行时错误。

那么问题来了,如果一定要比较两个切片、映射、函数的相等性,该如何操作呢?

reflect.DeepEqual 函数原型:

// 用于判断两个值是否深度一致
// 
// 除了类型相同;在可以时(主要是基本类型)会使用==;但还会比较array、slice的成员,
// map的键值对,结构体字段进行深入比对。map的键值对,对键只使用==,但值会继续往深
// 层比对。DeepEqual函数可以正确处理循环的类型。函数类型只有都会nil时才相等;空切
// 片不等于nil切片;还会考虑array、slice的长度、map键值对数。
func DeepEqual(x, y any) bool

对于 reflect.DeepEqual 而言,它通过牺牲程序的性能来弥补 == 运算符无法处理切片、映射、函数的短板,对于不支持 == 操作的类型,reflect.DeepEqual 函数会有一套自己的比较规则。

你可以把 reflect.DeepEqual 函数理解成是 == 运算符的扩展版!下面是一个简单的例子,演示了如何使用 reflect.DeepEqual 函数:

package mainimport "fmt"func main() {var a, b interface{}// 给 a 赋值为 int64 类型的 1a = int64(1)// 给 b 赋值为 int64 类型的 2b = int64(2)fmt.Println(a == b, reflect.DeepEqual(a, b))b = int64(1)fmt.Println(a == b, reflect.DeepEqual(a, b))b = float32(1)fmt.Println(a == b, reflect.DeepEqual(a, b))// 给 b 赋值为 int 类型的切片a, b = []int{1, 2, 3, 4, 5}, []int{1, 2, 3, 4, 5}fmt.Println(reflect.DeepEqual(a, b)) // trueb = []int{5, 4, 3, 2, 1}fmt.Println(reflect.DeepEqual(a, b)) // false
}

 

相关文章:

十分钟掌握Go语言==运算符与reflect.DeepEqual函数处理interface{}值的比较规则

在 Go 语言中,interface{} 类型是一种特殊的接口类型,它表示任意类型的值。你可以使用 运算符来检测任意两个 interface{} 类型值的相等性,比较的规则和一般的接口类型一样,需要满足以下条件: 两个 interface{} 值的…...

Unity3d Shader篇(一)— 顶点漫反射着色器解析

文章目录 前言一、顶点漫反射着色器是什么?1. 顶点漫反射着色器的工作原理 二、编写顶点漫反射着色器1. 定义属性2. 创建 SubShader3. 编写着色器程序段4. 完成顶点着色器5. 完成片段着色器 三、效果四、总结 前言 在 Unity 中,Shader 可以用来实现各种…...

WordPress主题YIA的文章页评论内容为什么没有显示出来?

有些WordPress站长使用YIA主题后,在YIA主题设置的“基本”中没有开启“一键关闭评论功能”,而且文章也是允许评论的,但是评论框却不显示,最关键的是文章原本就有的评论内容也不显示,这是为什么呢? 根据YIA主…...

选择低代码应该注意什么?如何选择?

我查看了几乎所有的介绍低代码的总结和分析报告,几乎都没有把低代码最底层的产品逻辑说清楚。今天我尝试不用复杂的技术名词,也不用代码,把这个事儿给大家说明白,低代码到底怎么回事儿!(人云亦云那些&#…...

橘子学linux调优之工具包的安装

今天在公司无聊的弄服务器,想着有些常用的工具包安装一下,这里就简单记录一下。 一、sysstat的安装和使用 1、安装 我是通过源码的方式安装的,这样的好处在于可以自由选择你的版本,很直观。 直接去github上找到sysstat的地址&a…...

函数的连续与间断【高数笔记】

【连续】 分类,分几个?每类特点? 连续条件,是同时满足还是只需其一? 【间断】 分类,分几个大类,又分几个小类?每类特点? 间断条件,是同时满足还是只需其一&am…...

游戏如何选择服务器

选择游戏服务器是一个综合性的过程,涉及到的因素包括但不限于游戏类型和规模、硬件配置、网络质量、安全性、服务商的声誉以及地理分布等。以下是一些具体的指导原则: 游戏类型和规模:根据游戏的具体需求来选择合适的服务器。例如&#xff0…...

ubuntu20安装mysql8

1.安装 sudo apt update sudo apt install mysql-server-8.0 -y2.查看运行状态 yantaoubuntu20:~$ sudo systemctl status mysql ● mysql.service - MySQL Community ServerLoaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset:>Active: active …...

07 SB3之@HttpExchange(TBD)

HttpExchange是SpringBoot3的新特性. Spring Boot3 提供了新的 HTTP 的访问能力,封装了Http底层细节. 通过接口简化 HTTP远程访问,类似 Feign 功能。 SpringBoot 中定义接口提供 HTTP 服务 --> 框架生成的代理对象实现此接口 --> 框架生成的代理…...

Redis数据淘汰策略

Redis作为一种高性能的键值存储数据库,通常用于缓存和提高数据检索速度。然而,由于内存资源有限,当内存不足以容纳所有数据时,Redis就需要采取一些策略来删除部分数据,以确保新的数据能够被写入。这就引入了数据淘汰策…...

Git的一些基本操作

初始git 我们给出下面的一个场景,在大学里,一些老师在我们做完实验之后喜欢让我们交实验报告,假设我们有一个比较追求完美的老师和一个勤奋的学生,这个学生叫做小帅,那天小帅桑勤奋的完成实验报告,在第二天…...

Spring Boot中异步线程池@Async

很多业务场景需要使用异步去完成,比如:发送短信通知。要完成异步操作一般有两种: 1、消息队列MQ 2、线程池处理。 我们来看看Spring框架中如何去使用线程池来完成异步操作,以及分析背后的原理。 一. Spring异步线程池的接口类 …...

ArcGIS学习(五)坐标系-2

3.不同基准面坐标系之间的转换 在上一关中,我们学习了ArcGIS中的投影(投影栅格)工具,并以"WGS1984地理坐标系与WGS1984的UTM投影坐标系的转换”为例进行讲解。 "WGS1984地理坐标系与WGS1984的UTM投影坐标系的转换”代表的是同一个基准面下的两个坐标的转换。 …...

2024Node.js零基础教程(小白友好型),nodejs新手到高手,(五)NodeJS入门——http模块

044_http模块_创建HTTP服务端 hello,大家好,那这个小节我们来使用 nodejs 创建一个 http 的服务,有了这个 http 服务之后,我们就可以处理浏览器所发送过来的请求,并且还可以给这个浏览器返回响应。 顺便说一下&#x…...

sklearn.preprocessing 标准化、归一化、正则化

文章目录 数据标准化的原因作用归一化最大最小归一化针对规模化有异常的数据标准化线性比例标准化法log函数标准化法正则化Normalization标准化的意义数据标准化的原因 某些算法要求样本具有零均值和单位方差;需要消除样本不同属性具有不同量级时的影响: ① 数量级的差异将导…...

Windows系统编程(一) 文件与目录操作

以下程序需要包含<Windows.h>头文件 创建打开文件 HANDLE hFile CreateFile("D:\\rkvir.ini", GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 此处打开文件&#xff0c;参数依次 已有文件的路径&#xff0c;注意…...

6-2、T型加减速计算简化【51单片机+L298N步进电机系列教程】

↑↑↑点击上方【目录】&#xff0c;查看本系列全部文章 摘要&#xff1a;本节介绍简化T型加减速计算过程&#xff0c;使其适用于单片机数据处理。简化内容包括浮点数转整型数计算、加减速对称处理、预处理计算 一、浮点数转整型数计算 根据上一节内容已知 常用的晶振大小…...

配置Jenkins自动构建打包项目

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 需求说明 1、给A项目配置jenkins每2小时无条件自动构建一次&#xff0c;无论是否有代码提交。 2、给B项目配置jenkins每15分钟检…...

进阶C语言-通讯录的实现

通讯录 🎈1.设计要求🎈2.程序实现🔭2.1打印菜单及初始化通讯录🔭2.2显示所有联系人🔭2.3查找指定的联系人🔭2.4删除指定的联系人🔭2.5查找指定的联系人🔭2.6修改指定联系人🔭2.7按照年龄排序(以此为例)🎈3.全部源码以及实现🎈1.设计要求 🌞通过前面…...

STM32单片机的基本原理与应用(七)

超声波测距实验 基本原理 超声波测距实验是STM32单片机通过控制HC-SR04超声波模块&#xff0c;使其发送超声波&#xff0c;遇到物体反射回超声波来实现距离测量&#xff0c;其原理就是在发射超声波到接收超声波会有一段时间&#xff0c;而超声波在空气中传播的速度为声速&…...

解锁3大自由:5分钟掌握的音乐格式解放工具

解锁3大自由&#xff1a;5分钟掌握的音乐格式解放工具 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 在数字音乐时代&#xff0c;我们却常常面临这样的困境&#xff1a;下载的音乐被限制在特定播放器中&#xff0c;就像拥有一本精美…...

Ostrakon-VL扫描终端部署:支持HTTPS与Basic Auth安全访问

Ostrakon-VL扫描终端部署&#xff1a;支持HTTPS与Basic Auth安全访问 1. 项目概述 Ostrakon-VL扫描终端是一款基于Ostrakon-VL-8B多模态大模型开发的Web交互应用&#xff0c;专为零售与餐饮行业场景优化设计。与传统工业级UI不同&#xff0c;该终端采用高饱和度的像素艺术风格…...

GLM-4-9B-Chat-1M与Dify平台集成:无代码长文本处理系统搭建

GLM-4-9B-Chat-1M与Dify平台集成&#xff1a;无代码长文本处理系统搭建 1. 引言 想象一下&#xff0c;你手头有一份200页的法律合同需要快速审核&#xff0c;或者需要分析整本学术专著的核心观点&#xff0c;甚至要处理多语言的长篇商业文档。传统的人工处理方式耗时耗力&…...

Bilibili-Evolved性能优化实战:突破60fps流畅播放全解析

Bilibili-Evolved性能优化实战&#xff1a;突破60fps流畅播放全解析 【免费下载链接】Bilibili-Evolved 强大的哔哩哔哩增强脚本 项目地址: https://gitcode.com/gh_mirrors/bi/Bilibili-Evolved Bilibili-Evolved作为强大的哔哩哔哩增强脚本&#xff0c;通过深度优化浏…...

护士执业资格考试历年真题及答案解析电子版PDF(2011-2025年)

2026年护士执业资格考试时间为2026年4月11-12日。‌‌为助力广大考生高效备考&#xff0c;小编精心整理了涵盖2011年至2025年的护士执业资格考试真题试卷及详细答案解析&#xff0c;包含《专业实务》和《实践能力》&#xff0c;高清PDF电子版&#xff0c;可打印&#xff0c;方便…...

教无人机操控3年,这款仿真软件让我彻底告别“真机实训焦虑”

作为无人机专业实操教师&#xff0c;深耕一线教学3年&#xff0c;最大的痛点莫过于“真机实训难”——相信同行们都有共鸣&#xff0c;无人机操控教学看似是“练手”&#xff0c;实则处处是坑&#xff0c;每一个难题都让人头疼不已&#xff0c;甚至一度让我陷入教学焦虑。整理了…...

开源小模型也能干大事:MinerU图文理解实战教程

开源小模型也能干大事&#xff1a;MinerU图文理解实战教程 1. 项目简介 OpenDataLab MinerU 是一个专门针对文档理解设计的智能多模态模型&#xff0c;基于 OpenDataLab/MinerU2.5-1.2B 模型构建。虽然只有 1.2B 参数&#xff0c;但这个模型在文档解析方面表现出色&#xff0…...

融合多尺度特征与注意力机制的YOLOv5红外小目标检测优化方案

1. 红外小目标检测的技术挑战 红外遥感图像中的小目标检测一直是计算机视觉领域的难点问题。与可见光图像相比&#xff0c;红外图像具有低对比度、高噪声、目标尺寸小等特点&#xff0c;这使得传统检测算法难以取得理想效果。在实际应用中&#xff0c;军事侦察中的无人机识别、…...

手把手教你部署M2FP:快速搭建人体部位识别服务

手把手教你部署M2FP&#xff1a;快速搭建人体部位识别服务 1. 引言&#xff1a;为什么选择M2FP进行人体解析&#xff1f; 在计算机视觉领域&#xff0c;人体解析&#xff08;Human Parsing&#xff09;是一项关键技术&#xff0c;它能够将图像中的人体划分为多个语义区域&…...

TinyCheck开发指南:从源码结构到核心类设计,理解网络安全检测平台架构

TinyCheck开发指南&#xff1a;从源码结构到核心类设计&#xff0c;理解网络安全检测平台架构 【免费下载链接】TinyCheck TinyCheck allows you to easily capture network communications from a smartphone or any device which can be associated to a Wi-Fi access point …...