
`|=`是go语言中的位或赋值运算符,用于对变量执行按位或(or)操作后将结果原地赋值给该变量,等价于`mode = mode | m`,常用于权限组合、状态标记等场景。
在Go中,|=属于复合赋值运算符(compound assignment operator),其语义为:
a |= b // 等价于 a = a | b
其中 | 是按位或(bitwise OR)运算符,对两个整数的操作数逐位进行逻辑或运算:只要某一位上至少有一个操作数为1,结果该位即为1。
在你提供的示例代码中:
func getPageInfoMode(r *http.Request) (mode PageInfoMode) {
for _, k := range strings.Split(r.FormValue("m"), ",") {
if m, found := modeNames[strings.TrimSpace(k)]; found {
mode |= m // 关键行:累积设置多个模式标志
}
}
return
}PageInfoMode 很可能是一个基于整数的位标志类型(如 type PageInfoMode uint8),而 modeNames 是一个将字符串映射到唯一比特位的字典,例如:
立即学习“go语言免费学习笔记(深入)”;
var modeNames = map[string]PageInfoMode{
"summary": 1 << 0, // 0b0001
"detail": 1 << 1, // 0b0010
"chart": 1 << 2, // 0b0100
"export": 1 << 3, // 0b1000
}当请求参数 m="summary,detail" 时,循环会依次执行:
- mode |= 0b0001 → mode = 0b0001
- mode |= 0b0010 → mode = 0b0011
最终 mode 同时承载了多个独立状态,这种设计高效、无冗余,且支持位运算快速校验(如 mode&detail != 0 判断是否启用 detail 模式)。
⚠️ 注意事项:
- |= 仅适用于整数类型(包括 int、uint、byte、自定义整型等),不支持浮点数或字符串;
- 操作数必须类型兼容(若 mode 是 PageInfoMode,则 m 也应为同类型或可隐式转换的整型);
- 与 += 类似,|= 是原子性复合操作,但不保证并发安全;多 goroutine 同时修改同一变量时需加锁或使用 sync/atomic;
- 不要与逻辑或 || 混淆:|| 作用于布尔表达式且具有短路特性,而 |= 是底层位操作,无短路行为。
✅ 总结:|= 是 Go 中实现位标志集合(bitmask)的核心语法糖,兼顾可读性与性能,广泛应用于配置解析、权限控制、状态机等系统编程场景。熟练掌握它,是写出地道、高效 Go 代码的重要一环。









