Golang 中哪些类型可以作为 map 类型的 key?
目录
可以作为 map 键的类型
不能作为 map 键的类型
最佳实践
小结
在 Go 语言中,map 是一种内置的关联数据结构类型,由一组无序的键值对组成,每个键都是唯一的,并与一个对应的值相关联。本文将详细介绍哪些类型的变量可以作为 map 的键,并通过实例进行说明。
可以作为 map 键的类型
因为 map 需要能够判断两个键是否相等以确保每个键的唯一性,所以并非所有类型都可以作为 map 的键,可以作为 map 键的数据类型必须满足以下条件:
- 可比较性(Comparable):用于定义 map 键的类型必须是可比较的,也就是说,Go 语言能够确定两个相同类型的键是否相等。这要求该类型支持 == 操作符来进行比较。
- 不可变性(Immutable):虽然 Go 语言规范并未明确指出键必须不可变,但由于 map的内部实现机制,键在创建后不能改变,因此通常选择不可变类型作为键。
以下是可以作为 map 键的类型:
- 基本类型,几乎所有的基本类型(整型、浮点型、字符串、布尔型等)都可以作为 map 的键,因为它们都支持相等性比较。
package mainimport "fmt"func main() {// 整数作为键mapInt := map[int]string{1: "one",2: "two",3: "three",}// 字符串作为键mapString := map[string]int{"Alice": 25,"Bob": 30,"Eve": 22,}// 浮点数作为键(不推荐,因为浮点数的比较可能会因精度问题导致不准确)mapFloat64 := map[float64]string{1.1: "one point one",2.2: "two point two",3.3: "three point three",}// 布尔值作为键mapBool := map[bool]string{true: "true",false: "false",}fmt.Println(mapInt, mapString, mapFloat64, mapBool)
}
- 指针类型,指针类型可以作为 map 的键,因为指针的比较是基于指向的内存地址的。简单示例代码如下:
package mainimport "fmt"func main() {type Person struct {Name stringAge int}alice := &Person{"Alice", 25}bob := &Person{"Bob", 30}mapPointer := map[*Person]string{alice: "Alice's pointer",bob: "Bob's pointer",}fmt.Println(mapPointer)
}
- 接口类型,接口类型可以作为 map 的键,只要接口的动态类型(即实际存储的类型)是可比较的。简单示例代码如下:
package mainimport "fmt"type Equalizer interface {Equal(Equalizer) bool
}type IntEqualizer intfunc (i IntEqualizer) Equal(e Equalizer) bool {other, ok := e.(IntEqualizer)return ok && i == other
}func main() {mapInterface := map[Equalizer]string{IntEqualizer(1): "one",IntEqualizer(2): "two",IntEqualizer(3): "three",}fmt.Println(mapInterface)
}
- 结构体类型,结构体类型可以作为 map 的键,只要其所有字段都是可比较的。简单示例代码如下:
package mainimport "fmt"func main() {type Point struct {X, Y int}mapStruct := map[Point]string{{1, 2}: "Point at (1,2)",{3, 4}: "Point at (3,4)",}fmt.Println(mapStruct)
}
- 数组类型,数组类型可以作为 map 的键,只要数组中的元素类型是可比较的。简单示例代码如下:
package mainimport "fmt"func main() {arr1 := [3]int{1, 2, 3}arr2 := [3]int{4, 5, 6}mapArray := map[[3]int]string{arr1: "123",arr2: "456",}fmt.Println(mapArray)
}
不能作为 map 键的类型
以下类型不能作为 map 的键:
- 切片类型,因为切片是引用类型,其内容可能会变化,使得比较操作不确定。
- 函数类型,因为 Go 语言中没有为函数定义相等性比较操作。
- map 类型,map 类型不能作为 map 的键,因为也是引用类型,且没有定义相等性比较操作。
- 包含上述不可比较类型的复合类型,任何包含上述不可比较类型(如切片、函数、映射)的复合类型,如结构体,也不能作为 map 的键。
最佳实践
- 使用不可变类型作为键,map 的键必须是可比较的类型,可以使用任何内置的可比较类型,如 int、string、float 等。
- 如果键是自定义类型,需要使该类型必须支持 == 和 != 比较运算。
- 如果使用结构体作为键,需要保证结构体的字段不会被修改。如果结构体的字段发生变化,可能会导致无法找到键值对。
- 虽然指针可以作为键,但是两个相同内容的不同指针会被视为不同的键。
- 字符串作为键时,尤其是在有大量独特字符串时,可能会导致内存使用的增加。这种情况下,可以考虑使用字符串的哈希值作为键,但要注意潜在的散列冲突。
- 最小化键的大小,更小的键可以减少内存的占用,同时可以提高查找的效率。
小结
在 Go 语言中,只有那些不可变并且可比较的类型才能作为 map 的键。在日常编程中,应该选择合适的键类型以确保 map 的高效和准确性。
相关文章:
Golang 中哪些类型可以作为 map 类型的 key?
目录 可以作为 map 键的类型 不能作为 map 键的类型 最佳实践 小结 在 Go 语言中,map 是一种内置的关联数据结构类型,由一组无序的键值对组成,每个键都是唯一的,并与一个对应的值相关联。本文将详细介绍哪些类型的变量可以作为…...
C# 导出EXCEL 和 导入
使用winfrom简单做个界面 选择导出路径 XLSX起名字 打开导出是XLSX文件 // 创建Excel应用程序对象Excel.Application excelApp new Excel.Application();excelApp.Visible false;// 创建工作簿Excel.Workbook workbook excelApp.Workbooks.Add(Type.Missing);Excel.Works…...
学网络必懂的华为CSS堆叠技术
知识改变命运,技术就是要分享,有问题随时联系,免费答疑,欢迎联系! 厦门微思网络https://www.xmws.cn 华为认证\华为HCIA-Datacom\华为HCIP-Datacom\华为HCIE-Datacom Linux\RHCE\RHCE 9.0\RHCA\ Oracle OC…...
SV-7041T 30W网络有源音箱校园教室广播音箱,商场广播音箱,会议广播音箱,酒店广播音箱,工厂办公室广播音箱
SV-7041T 30W网络有源音箱 校园教室广播音箱,商场广播音箱,会议广播音箱,酒店广播音箱,工厂办公室广播音箱 SV-7041T是深圳锐科达电子有限公司的一款2.0声道壁挂式网络有源音箱,具有10/100M以太网接口,可将…...
Could NOT find Threads (missing: Threads_FOUND)
具体错误 -- Performing Test CMAKE_HAVE_LIBC_PTHREAD -- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed -- Looking for pthread_create in pthreads -- Looking for pthread_create in pthreads - not found -- Looking for pthread_create in pthread -- Looking for…...
1114: 逆序(数组)
题目描述 输入n(1<n<10)和n个整数,逆序输出这n个整数。 输入 输入n(1<n<10),然后输入n个整数。 输出 逆序输出这n个整数,每个整数占4列,右对齐。 样例输入 6 4 5…...
uniapp如何调用ANDROID原生函数
在 UniApp 中调用 Android 原生函数,通常需要使用 UniApp 的插件系统。以下是调用 Android 原生函数的一般步骤: 安装插件:首先,确保你已经安装了对应的插件。你可以在 UniApp 插件市场 中搜索并安装你需要的插件。对于 Android 原…...
python 字符串的详细处理方法
当前版本: Python 3.8.4 简介 字符串是由字符组成的序列,可以用单引号、双引号或三引号(单引号或双引号的连续使用)括起来。一般用来表示和处理文本信息,可以是字母、数字、标点符号以及其他特殊字符,用于…...
蓝桥杯AcWing学习笔记 8-2数论的学习(下)
蓝桥杯 我的AcWing 题目及图片来自蓝桥杯C AB组辅导课 数论(下) 蓝桥杯省赛中考的数论不是很多,这里讲几个蓝桥杯常考的知识点。 约数个数定理 我们如何去求一个数的约数个数呢? N N N分解质因数的结果: N P 1 α…...
vcs makefile
主要参考: VCS使用Makefile教程_vcs makefile-CSDN博客https://blog.csdn.net/weixin_45243340/article/details/129255218?ops_request_misc%257B%2522request%255Fid%2522%253A%2522170524049516800227431373%2522%252C%2522scm%2522%253A%252220140713.1301023…...
《Training language models to follow instructions》论文解读--训练语言模型遵循人类反馈的指令
目录 1摘要 2介绍 方法及实验细节 3.1高层次方法论 3.2数据集 3.3任务 3.4人体数据收集 3.5模型 3.6评价 4 结果 4.1 API分布结果 4.2公共NLP数据集的结果 4.3定性结果 问题 1.什么是rm分数 更多资料 1摘要 使语言模型更大并不能使它们更好地遵循用户的意图。例…...
Redis的实现二: c、c++的网络通信编程技术,让服务器处理多个client
看过上期的都知道,我是搞java的,所以对这些可能理解不是很清楚,各位看完可以尽情发言。 事件循环和非阻塞IO 在服务器端网络编程中,有三种处理并发连接的方法。 它们是:分叉、多线程和事件循环。分叉为每个客户端连接创建新…...
QT上位机开发(动画效果)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 不管是仿真,还是对真实环境的一比一模拟,动画都是非常好的一种呈现方式。目前在qt上面,实现动画主要有两种方法…...
手写实现 bind 函数
Function.prototype.myBind function(context) {if (typeof this ! function) {return}const args [...arguments].slice(1)const fn thisreturn function Fn() {// 判断函数作为构造函数的情况,这个时候需要传入当前的函数的this给apply调用,其余情况…...
安卓Android Studio读写MifareOne M1 IC卡源码
本示例使用的发卡器:https://item.taobao.com/item.htm?id615391857885&spma1z10.5-c-s.w4002-21818769070.11.3d2f789eOUPJBK <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xm…...
一二三应用开发平台文件处理设计与实现系列之5——MinIO技术预研
背景 上篇介绍了文件读写框架设计与实现,同时顺便说明了本地磁盘存储模式的实现模式。 今天来说下基于文件读写框架,如何集成对象存储组件minio,集成之前,需要对minio进行必要的了解,本篇是minio的技术预研。 minio简…...
Native.js是什么
Native.js 是一个开源项目,旨在通过 JavaScript 调用原生 Android API。它的目标是让 JavaScript 开发者能够使用 Android 原生 API,从而在不编写原生代码的情况下构建 Android 应用。 使用 Native.js,开发者可以使用 JavaScript 调用 Andro…...
Vant-ui图片懒加载
核心代码 在你的全局顶部引入和初始化 Vue.use(vant.Lazyload, {loading: /StaticFile/img/jiazai.jpg,error: /StaticFile/img/jiazai.jpg,lazyComponent: false, });//图片懒加载 <img v-lazy"https://img-blog.csdnimg.cn/direct/3d2c8a7e2c0040488a8128c3e381d58…...
创建EasyCodeMybatisCodeHelperPro模板文件用于将数据库表生成前端json文件
在intellij idea中,通过插件EasyCodeMybatisCodeHelperPro,从现有的模板文件中选择一个复制粘贴,然后稍为修改,即可得到一个合适的模板文件。 现在的前端,越来越像后端。TypeScript替代了JavaScript,引入了…...
华为端口安全常用3种方法配置案例
安全动态mac地址学习功能 [Huawei]int g0/0/01 interface GigabitEthernet0/0/1 port-security enable //开启安全 port-security max-mac-num 2 //最多为2个mac地址学习 port-security protect-action restrict //丢包带警告 port-security aging-time 1 //mac地址的老化时间…...
ARM调试寄存器DBGCLAIMCLR详解与应用
1. ARM调试寄存器概述 在嵌入式系统开发中,调试寄存器是连接开发者和硬件的重要桥梁。作为ARM架构调试系统的核心组件,DBGCLAIMCLR这类专用寄存器提供了底层硬件级别的调试能力。不同于普通的存储器映射寄存器,调试寄存器通过系统寄存器空间进…...
多物流机器人任务调度与路径规划【附程序】
✨ 长期致力于物流机器人、任务调度、路径规划、沙猫群算法研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流,点击《获取方式》 (1)栅格-拓扑双层地图建模与任务分配…...
基于Java的教学仪器设备销售网站(10017)
有需要的同学,源代码和配套文档领取,加文章最下方的名片哦 一、项目演示 项目演示视频 二、资料介绍 完整源代码(前后端源代码SQL脚本)配套文档(LWPPT开题报告/任务书)远程调试控屏包运行一键启动项目&…...
从零构建Copaw自定义Channel:WebSocket实时通信与Agent能力接入实战
1. 项目概述:一个最小可用的Copaw自定义Channel实现如果你正在研究如何将Copaw Agent的能力“暴露”给外部世界,比如一个网页、一个桌面应用,或者你自己的业务系统,那么你很可能已经意识到,官方文档里关于Channel的示例…...
别盲目学AI!先搞懂人工智能的3大核心分支,选对方向少走3年弯路
文章目录前言第一大分支:大模型与生成式AI——AI行业的"水电煤"什么是大模型与生成式AI?大模型技术在2026年的发展现状大模型方向的主要岗位和薪资大模型方向的学习路线第二大分支:智能体与多智能体系统——2026年AI行业最大的风口…...
从手机拍照到工业质检:聊聊自适应白平衡算法在实际项目里的那些‘坑’
从手机拍照到工业质检:自适应白平衡算法的实战避坑指南 在工业视觉检测线上,一台价值百万的自动化设备突然频繁误判产品颜色——原因竟是车间顶灯老化导致色温偏移,而算法团队引以为傲的"完美反射"白平衡模型完全失效。类似场景每天…...
别再只用流水灯了!用Arduino和74HC595驱动数码管/点阵屏的完整教程
从流水灯到智能显示:74HC595驱动数码管与点阵屏的实战指南 在创客社区里,74HC595移位寄存器几乎成了"流水灯"的代名词——无数入门教程用它来演示如何用少量IO口控制多颗LED。但当你真正需要构建一个电子钟、温湿度显示器或简易信息板时&#…...
STM32模拟I2C驱动TCS34725实现环境光与颜色识别
1. 环境光与颜色识别的硬件搭档 当我们需要让设备感知周围环境的光线强弱,或者识别物体的具体颜色时,TCS34725这颗传感器绝对是性价比之选。它不仅能测量环境光强度,还能通过RGB三原色的比例来判断颜色,这在智能家居和工业检测中特…...
技术解析:OBS Source Record - 独立源录制解决方案
技术解析:OBS Source Record - 独立源录制解决方案 【免费下载链接】obs-source-record 项目地址: https://gitcode.com/gh_mirrors/ob/obs-source-record OBS Source Record插件通过创新的滤镜架构,解决了多源独立录制的技术难题,为…...
5G网络部署挑战与云原生技术解决方案
1. 5G网络部署的核心挑战与技术演进5G作为第五代移动通信技术,正在全球范围内加速商用部署。与4G网络相比,5G在峰值速率、连接密度和时延等关键指标上实现了数量级提升。这种性能飞跃主要依赖于三项关键技术突破:Massive MIMO(大规…...
