用 struct{} 能省内存但仅限特定场景;map[string]struct{} 通过编译器优化省 value 存储,需写 m["key"] = struct{}{},100 万 key 约省 1mb;chan struct{} 发送必须带字面量,接收可忽略。

用 struct{} 真能省内存,但只在特定场景下生效;盲目替换 map[string]bool 或往结构体里塞它,反而可能引入对齐开销或 GC 干扰。
map value 用 struct{} 确实省空间,但得写对赋值语法
编译器对 map[string]struct{} 的 value 层做了特殊优化:不分配存储,跳过写入。但你必须显式写 m["key"] = struct{}{},不能简写成 m["key"] = {}(语法错误)。
实际节省量取决于 key 数量——100 万个 key 时,比 map[string]bool 少约 1MB value 存储;但哈希桶本身的元数据开销仍存在,不是线性节省。
chan struct{} 发送信号必须带字面量,接收可忽略
ch 是唯一合法的发送写法;<code>ch 直接报错,<code>ch 也不行(缺少类型标识)。接收端可用 <code> 忽略值,或 <code>_ := 显式丢弃。<br>缓冲通道 <code>make(chan struct{}, N) 中,N 可设为 1e6 甚至更大,底层不为每个元素分配内存;而 make(chan bool, N) 会真实分配 N 字节,可能触发 page fault。
嵌入 struct{} 到结构体里,不一定“零成本”
它自身 size 是 0,unsafe.Sizeof 返回 0,但位置影响字段偏移:
• 在中间(如 type T struct { x int64; _ struct{}; y int32 }):y 起始偏移卡在 x 结束处(offset=8),不额外占位但改变对齐边界
• 在末尾:可能触发填充(防止指针悬空),导致结构体总大小变大
• 用 *struct{} 更糟:指针本身 8 字节,还进 GC 扫描队列,完全抵消优势
别把它当万能占位符,容易忽略的其实是语义
空结构体真正不可替代的地方,是表达「只关心事件发生,不传任何数据」——比如退出通知、并发限流、集合成员标记。一旦开始考虑“要不要存点状态”,就该换类型了。它的零内存特性只在按元素分配的容器(map、chan、[]struct{})里起作用,嵌入、指针、方法接收器这些场景,省下的字节常被对齐和 GC 成本吃掉。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











