Golang里空结构体struct{}的介绍和使用

s t r u c t struct struct G o l a n g Golang Golang里的关键字,用于定义结构类型
比如

type Student struct{id intname string
}

struct{}是有 0 0 0个元素的结构体.
struct{}{}表示类型struct{}的值为空{}

1.性质

1.1不占用内存

大小为 0 0 0,不需要内存来存储struct{}类型的值。

func Test_Size(t *testing.T) {var x intvar y stringvar z struct{}t.Log(unsafe.Sizeof(x), unsafe.Sizeof(y), unsafe.Sizeof(z)) //8 16 0
}

在这里插入图片描述

1.2 地址相同

定义两个struct{}类型的变量,打印并比较其地址,发现是相同的

func Test_Address(t *testing.T) {var x struct{}var y struct{}t.Logf("%p %p %v %v", &x, &y, &x == &y, x == y) // 0x1290460 0x1290460 true true
}

在这里插入图片描述

2.用途

2.1实现set

golang里没有实现set,如果在使用map的时候只关心key,不关心value的话,可以借助struct{}来实现set。比如key为string类型,那么set的实现map[string]struct{}。
因为struct{}不占用空间,所以在查找和判断的过程中速度会快,而且占用的内存也会小
简单实现:

func Test_set(t *testing.T) {set := make(map[string]struct{})set["a"] = struct{}{}if _, ok := set["a"]; ok {t.Log("exists") //exists}
}

在这里插入图片描述

使用interface{}实现

type Set map[interface{}]struct{}func (s Set) Add(item interface{}) {s[item] = struct{}{}
}func (s Set) Remove(item interface{}) {delete(s, item)
}func (s Set) Contains(item interface{}) bool {_, exists := s[item]return exists
}func Test_any_set(t *testing.T) {set := make(Set)set.Add("apple")set.Add("banana")set.Add("orange")fmt.Println("Set:", set)fmt.Println("Contains apple:", set.Contains("apple"))fmt.Println("Contains grape:", set.Contains("grape"))set.Remove("banana")fmt.Println("Set:", set)
}

在这里插入图片描述
使用泛型实现:

type Set[T comparable] map[T]struct{}func (s Set[T]) Add(v T) {s[v] = struct{}{}
}func (s Set[T]) Remove(v T) {delete(s, v)
}func (s Set[T]) Contains(v T) bool {_, ok := s[v]return ok
}func (s Set[T]) Len() int {return len(s)
}func (s Set[T]) Values() []T {values := make([]T, 0, s.Len())for v := range s {values = append(values, v)}return values
}func Test_any_set(t *testing.T) {s := Set[string]{}s.Add("apple")s.Add("banana")s.Add("orange")fmt.Println("Set:", s.Values())fmt.Println("Contains apple:", s.Contains("apple"))fmt.Println("Contains grape:", s.Contains("grape"))s.Remove("banana")fmt.Println("Set:", s.Values())
}

在这里插入图片描述

2.2. 用于无数据的channel

有的时候 c h a n n e l channel channel不需要发送数据,只需要一个触发信号,就可以使用struct{}来减少信号传递过程中的内存开销
a. 等待协程完成
w o r k e r worker worker函数是一个协程,它会模拟一些工作并在完成后发送空结构体值到 d o n e done done通道。
T e s t _ w a i t Test\_wait Test_wait函数中,我们通过从 d o n e done done通道接收空结构体值来等待工作完成。

func worker(done chan struct{}) {fmt.Println("Worker: Performing some work...")time.Sleep(2 * time.Second)fmt.Println("Worker: Work completed!")done <- struct{}{} // 发送空结构体值表示工作完成
}
func Test_wait(t *testing.T) {done := make(chan struct{})go worker(done)<-done // 接收空结构体值,等待工作完成t.Log("Main: Done!")
}

在这里插入图片描述

b.触发事件
w a i t F o r E v e n t waitForEvent waitForEvent函数会等待接收到空结构体值,表示事件发生。
t r i g g e r E v e n t triggerEvent triggerEvent函数会在一段时间后发送空结构体值到event通道,表示事件发生。
通过使用空结构体值作为通道元素,我们可以简单地实现事件的触发和等待。

func waitForEvent(event chan struct{}) {fmt.Println("Waiting for event...")<-event // 等待接收到空结构体值,表示事件发生fmt.Println("Event received!")
}func triggerEvent(event chan struct{}) {time.Sleep(2 * time.Second)fmt.Println("Triggering event...")event <- struct{}{} // 发送空结构体值,表示事件发生
}
func Test_event(t *testing.T) {event := make(chan struct{})go waitForEvent(event)go triggerEvent(event)time.Sleep(3 * time.Second)
}

在这里插入图片描述

2.3 方法接收器

实现一个接口,只需要实现一些方法,不用声明一些额外的数据,可以用struct{}来实现,也可以换成其他任意的变量,比如 i n t int int b o o l bool bool

type Animal interface {Shouting()
}
type Dog struct{}func (dog *Dog) Shouting() {fmt.Println("wang wang wang")
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/598750.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大创项目推荐 深度学习卷积神经网络的花卉识别

文章目录 0 前言1 项目背景2 花卉识别的基本原理3 算法实现3.1 预处理3.2 特征提取和选择3.3 分类器设计和决策3.4 卷积神经网络基本原理 4 算法实现4.1 花卉图像数据4.2 模块组成 5 项目执行结果6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基…

windowns虚拟机(jdk下载 tomcat下载 mysql下载 发部署项目)

1.启动服务&#xff08;远程连接&#xff09; 2.查看ip 3.右击计算机属性&#xff0c;高级设置&#xff0c;允许远程连接 4.打开本机远程连接&#xff08;administrator&#xff09; 5.jdk下载 将压缩包复制到桌面&#xff0c;双击安装 管理员身份打开黑窗口 输入Java查…

开启物联网的魔法之门 - 深入探索发布/订阅模式

文章目录 MQTT 发布/订阅模式MQTT 发布/订阅中的消息路由MQTT 与 HTTP 请求响应MQTT 与消息队列Paho Java 使用示例结语 MQTT 发布/订阅模式 发布订阅模式&#xff08;Publish-Subscribe Pattern&#xff09;是一种消息传递模式&#xff0c;它将发送消息的客户端&#xff08;发…

如何使用可视化管理工具DockerUI远程管理docker容器

文章目录 前言1. 安装部署DockerUI2. 安装cpolar内网穿透3. 配置DockerUI公网访问地址4. 公网远程访问DockerUI5. 固定DockerUI公网地址 前言 DockerUI是一个docker容器镜像的可视化图形化管理工具。DockerUI可以用来轻松构建、管理和维护docker环境。它是完全开源且免费的。基…

地址变量与函数进阶

指针与函数的高级用法 1.数组2.函数的重载3.函数的指针类型参数4.可变参数函数链表5.函数指针6.指针函数7.内联函数8.总结 在上节中我们简单谈论了指针变量&#xff0c;这节我们就来讨论指针变量的实际应用。 1.数组 相信有一定C语言基础的小伙伴一定很熟悉这个类型。数组可以…

【C++期末编程题题库】代码+详解18道

适合期末复习c看&#xff0c;或者刚入门c的小白看&#xff0c;有的题会补充知识点&#xff0c;期末复习题的代码一般比较简单&#xff0c;所以语法上没那么严谨。本文所有题目要求全在代码块的最上面。 目录 1、设计复数类 2、设计Computer类 3、实现相加的函数模板 4、圆类…

删除数组中的重复项

给你一个有序数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使得出现次数超过两次的元素只出现两次 &#xff0c;返回删除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 class Sol…

wait 和 notify 这个为什么要在synchronized 代码块中?

一个工作七年的小伙伴&#xff0c;竟然不知道” wait”和“notify”为什么要在 Synchronized 代码块中 。 好吧&#xff0c;如果屏幕前的你也不知道&#xff0c;请在公屏上刷”不知道“。 对于这个问题&#xff0c;我们来看看普通人和高手的回答。 一、问题解析 1. wait 和 n…

LLM之Agent再探

文章目录 前言思考解决办法总结前言 重要: 阅读该文章之前,一定要先阅读:LLM之Agent初探 1、当业务中有大量的tool时,比如有上千个,这些tool的描述加起来,总长度已经大大超过了LLM的最大输入长度,即使能接受这么长的token,从attention机制来看,效果也好不到哪里去。…

git 使用场景 本地分支 推送到 远程分支

本地分支推送到远程分支 git push origin <本地分支名>:<远程分支名> 将本地分支 推送到 远程指定分支 git push origin <本地分支名> 将本地分支 推送到 与本地分支同名的远程分支 git push …

线程同步之:QMutex\QMutexLocker

1、基于互斥量的线程同步类QMutex 2、lock() 与 unlock()必须配对使用。 2.1 lock() unlock() 2.2 tryLock() unlock() 3、QMutexLocker()是另一个简化了互斥量处理的类。在QMutexLocker实例变量的“生命周期”内的代码段 得到保护。 QMutexLocker的构造函数接受要给互斥量…

yolov5旋转目标检测-遥感图像检测-无人机旋转目标检测(附代码和原理)

目前&#xff0c;无人机技术的快速发展带来了遥感图像处理领域的革命性改变。然而&#xff0c;由于无人机在飞行时可能会出现旋转的情况&#xff0c;因此对于旋转目标的检测也成为了一个重要的问题。针对这个问题&#xff0c;yolov5可以提供一种高效的解决方案。 以下是介绍的分…

秋招复习之哈希表

目录 前言 1 哈希表 哈希表常用操作 哈希表简单实现 哈希冲突与扩容 2 哈希冲突 链式地址 开放寻址 线性探测 平方探测 多次哈希 编程语言的选择 3 哈希算法 哈希算法的目标 哈希算法的设计 常见哈希算法 数据结构的哈希值 总结 前言 秋招复习之哈希表。 1 哈希表 「哈希表 h…

万界星空科技云MES,助力客户快速构建数字工厂

一、MES发展趋势 1、定制化趋势 工业2.0、3.0的技术已较为成熟&#xff0c;部分制造业水平较为发达的国家已经率先进入以网络化、智能化为代表的工业4.0发展阶段,MES作为制造业规划层随着物联网等持续发展&#xff0c;为适应定制化时代&#xff0c;整体技术模块化、服务化将重…

防蓝光护眼台灯哪个牌子好?2024护眼灯315合格产品

最近身边的宝妈们都来问我这个已有两个娃的老司机&#xff0c;刚上小学就是近视了&#xff0c;买什么台灯给家里孩子能保护视力&#xff0c;经过小学门口时&#xff0c;真的是戴眼镜的小朋友占多数&#xff0c;搜索了我国的近视数据&#xff0c;中国的人口有14亿人左右&#xf…

Chromedriver 下载和安装指南

1. 确定Chrome浏览器版本 首先&#xff0c;在谷歌浏览器中找到当前版本信息。 打开“设置”&#xff0c;点击“关于谷歌”即可看到版本号。确保后续下载的Chromedriver版本与Chrome浏览器版本一致。或者直接跳转网页地址&#xff1a;chrome://settings/help 2. 下载Chromedri…

ShardingSphere-JDBC初探

引言 为什么使用分库分表&#xff1f; 数据量太大单表放不下&#xff0c;并且公司不希望切换产品&#xff0c;可选的方案不多&#xff0c;ShardingSphere就是不错的选择。 切换产品指的是换成es、clickhouse、hbase这种支持大数据&#xff0c;试想一下切换产品对整个项目的改…

React监听窗口宽度变化 触发resize(Hooks版本)

需求场景&#xff1a; 项目中有些样式&#xff0c;需要监听窗口大小更改&#xff0c;做一些自适应处理 Code&#xff1a; const [screenW, setScreenW] useState(document.documentElement.clientWidth || document.body.clientWidth)// 一些用到的需要自适应的变量const mi…

Linux第18步_安装“Ubuntu系统下的C语言编译器GCC”

Ubuntu系统没有提供C/C的编译环境&#xff0c;因此还需要手动安装build-essential软件包&#xff0c;它包含了 GNU 编辑器&#xff0c;GNU 调试器&#xff0c;和其他编译软件所必需的开发库和工具。本节用于重点介绍安装“Ubuntu系统下的C语言编译器&#xff27;&#xff23;&a…

电子化学品,预计2025年会增长到4302亿美元

电子化学品市场是一个庞大的细分市场&#xff0c;它包括了广泛的化学品种类&#xff0c;如涂料、塑料、精细化学品、农药和医药等。这个市场的发展相当迅速&#xff0c;下面我们将从全球市场和中国市场两个方面对其发展趋势进行分析。全球市场分析&#xff1a; 从全球市场的角度…