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

字面量struct{}代表了什么?又有什么用处?-Go语言

struct{} 在 Go 里代表空结构体类型。它的一个值 struct{}{} 不包含任何字段,不占用任何内存空间(大小为 0 字节),并且所有的空结构体值都共享同一个底层地址(通常是全局的 zerobase)。

它最主要的用途是:只关注“有没有”,完全不关注“是什么”,并且追求零内存开销


1. 作为通道的信号(通知机制)

当通道只用来传递“发生了一件事”,而不需要传递具体数据时,使用 chan struct{} 是最好的选择,因为发送一个空结构体不额外分配内存。

done := make(chan struct{})go func() {// 执行一些任务...close(done) // 通过关闭通道来发出”完成“信号
}()<-done // 阻塞直到接收到信号

这种模式在控制 goroutine 的退出、等待任务完成时非常常见。相比 chan boolchan struct{} 语义更清晰:这个通道只是用来发信号,不是传值


2. 实现集合 (Set)

Go 没有内置的 set 类型,通常用 map[T]bool 来模拟。但 bool 要占 1 字节,换成 struct{} 后,value 完全不占空间。特别当集合很大时,能节省可观的内存。

// 一个字符串集合
set := make(map[string]struct{})// 添加元素
set["apple"] = struct{}{}
set["banana"] = struct{}{}// 检查元素是否存在
if _, ok := set["apple"]; ok {fmt.Println("apple 在集合中")
}// 删除元素
delete(set, "apple")

struct{}{} 写起来略长,通常会定义一个类型别名简化:

type void = struct{}
set := make(map[string]void)
set["key"] = void{}

3. 仅携带方法,不存储数据

有些类型不需要任何状态,只需方法。用 struct{} 做接收者,定义一组函数,既为零大小,又防止误操作字段。

type Logger struct{}func (Logger) Info(msg string) {log.Println("[INFO]", msg)
}var logger Logger
logger.Info("something")

常用于接口实现:一个类型需要满足某个接口,但又不需要状态。空结构体因为没有字段,自然没有任何内存开销。


4. 作为嵌入类型,不增加结构体大小

struct{} 嵌入到其他结构体中,可以利用方法提升,但不会增加新结构体的大小。

type A struct {Name string
}type B struct {struct{} // 零大小嵌入A
}func (struct{}) Helper() { fmt.Println("helper") }var b B
b.Helper()  // B 获得了 Helper 方法,但本身大小仍是 Name 的大小

通常用于实现某些接口,或提供工具方法,但不希望引入额外内存。


5. 防止 key 冲突(context 上下文键)

context.WithValue 中,用自定义类型(尤其是空结构体类型)作为键,能避免不同包之间的 key 冲突。

type contextKey struct{}var key = contextKey{}ctx := context.WithValue(context.Background(), key, "value")
v := ctx.Value(key) // "value"

由于 struct{} 类型是唯一的(每个不同定义都是新类型),用它能完全避免与字符串 key 冲突。


总结一下 struct{} 的价值:

用途 为什么用它
chan struct{} 零内存通知,语义明确“只发信号不传值”
map[T]struct{} 省内存的集合,只关心键的存在
方法接收者 实现无状态类型,大小为零
嵌入字段 获得方法但不变大
上下文键 唯一类型避免冲突

struct{} 是 Go 里表达“占位符”“信号”“无数据”的最高效工具,大小始终是 0,完全为语义和性能服务。

http://www.jsqmd.com/news/795725/

相关文章:

  • YOLOv5网络结构里的‘分辨率魔术’:从608到640,输入尺寸如何悄悄改变你的特征图与Anchor分配?
  • 深度解析VinXiangQi:基于YOLOv5的智能象棋连线工具实战指南
  • 用Python玩转AD7606:一个Python包搞定八通道高速数据采集(附避坑指南)
  • Linux 新硬件适配实战:为 Realtek 8852 WiFi6 网卡手动编译驱动(Ubuntu/Manjaro 双教程)
  • 嵌入式Linux开发避坑:手把手教你交叉编译全套WiFi工具链(iw、wpa_supplicant、hostapd)
  • 如何在Windows上轻松实现多设备文件同步:SyncTrayzor完整使用教程
  • D2DX终极指南:让经典暗黑破坏神2在现代PC上焕然一新的5个步骤
  • 2026年亲测收藏:7款免费降AI率工具汇总,论文高效降AI轻松过知网! - 降AI实验室
  • Python量化交易实战:基于pyalgostrategypool的策略开发与部署全流程
  • 3步如何用Layerdivider实现智能图像分层,5分钟完成自动PSD转换
  • 如何选择单北斗GNSS变形监测系统:2026年高评选产品推荐榜单
  • WarcraftHelper:魔兽争霸3终极优化指南 - 5分钟解决游戏卡顿与兼容问题
  • inZOI 修改器下载2026最新版
  • 别再傻傻用MD5存密码了!PostgreSQL pgcrypto模块的crypt()函数实战避坑指南
  • 3步实现Windows风扇智能控制:FanControl终极配置指南
  • 保姆级教程:用CVAT的Track Mode高效标注视频,5分钟搞定目标追踪
  • 《实战》- 之- 零成本构建Windows个人云盘:HFS+内网穿透全攻略
  • 喜马拉雅音频下载终极指南:跨平台GUI工具完整使用教程
  • 基于MCP协议的智能发票解析:让AI智能体秒变财务专家
  • 给硬件工程师的IGBT参数速查手册:从数据手册到实际选型,这16个参数别再搞混了
  • 除了安装,VNC Viewer 6.20 这几个高效功能与安全设置你调了吗?
  • 娱乐圈天降紫微星实力为王,海棠山铁哥不靠背景只凭硬功底
  • BetterRTX:为Minecraft基岩版开启专业级光影体验的现代化安装器
  • 2026重庆旧房翻新装修公司哪家好?老房改造价格明细 - 大渝测评
  • 3分钟学会B站视频备份:用m4s-converter拯救你的珍贵收藏
  • PageHelper分页失效排查指南:从‘总页数总是第一页’到精准定位
  • 音乐格式的破壁者:ncmdump赋予你真正的音频自由
  • 【AI原生云原生融合实战白皮书】:SITS 2026官方认证K8s for AI部署清单(含GPU调度/LLM推理/模型热加载3大生产级配置)
  • 2026年3月测评选出,靠谱运动医学厂家哪家好有答案,市面上运动医学实力厂家大江医疗引领行业标杆 - 品牌推荐师
  • 如何永久保存微信聊天记录?终极备份与深度分析完整指南