比 && 先算,因为算术运算符 + 属于 arithmetic 组,&& 属于 logical 组,go 中 arithmetic 优先级高于 logical。

Go 里 + 和 && 谁先算?别靠猜,看这张表
Go 的运算符优先级是固定且明确的,不是“差不多就行”的经验判断。它不按数学直觉走,也不照搬 C 或 JavaScript —— 比如 && 优先级比 == 低,但比 = 高;+ 和 - 同级,但都比 == 高。写 a + b == c && d 时,实际等价于 ((a + b) == c) && d,不是 a + (b == c && d)。
常见错误现象:if x & y == 0 本意是“x 和 y 的按位与结果为 0”,但实际被解析为 x & (y == 0),因为 == 优先级高于 &。编译不报错,但逻辑全错。
- 查权威依据:直接翻 Go 语言规范 Operators 小节,里面按从高到低列了 5 大组(Unary、Arithmetic、Shift、Relational、Logical)
- 实战建议:只要涉及混合运算(尤其含
&、|、^、&&、||),一律加括号。这不是啰嗦,是防错成本最低的方式 - 注意
!=和==同级,但都低于算术运算;&&和||是最低的逻辑层,只比赋值=高一点点
1 算出来是 32 还是 128?
这是 Shift 运算符(、<code>>>)和算术运算混用的典型场景。Go 规定:Shift 的优先级和 +、- 相同,但**左结合**。所以 1 等价于 <code>(1 ,结果是 <code>8 + 2 = 10,不是 1 的 32。
使用场景:位掩码计算、协议字段偏移、哈希桶索引等对位操作敏感的地方。
立即学习“go语言免费学习笔记(深入)”;
- 如果本意是
1 ,必须显式加括号。Go 不会自动把加法“塞进”移位右边 右边的操作数必须是无符号整数类型(或能隐式转为 <code>uint),否则编译报错:invalid operation: shift of type int- 右移
>>同理,且对负数右移行为是实现定义的(通常按补码算术右移),别依赖
为什么 a || b && c 不等于 (a || b) && c?
因为 && 优先级高于 ||,所以 a || b && c 实际等价于 a || (b && c)。这和大多数语言一致,但容易和自然语言“或者…并且…”的语序混淆。
常见错误现象:写权限校验 isAdmin || isOwner && isSameTeam,本想表达“管理员,或者(所有者且同队)”,结果代码执行的是“管理员,或者(所有者且同队)”,逻辑没错——但若误以为是 (isAdmin || isOwner) && isSameTeam,就会漏放行。
- 短路求值规则不变:
||左边为 true 就跳过右边,&&左边为 false 就跳过右边 - 混合多个逻辑运算符时,优先级顺序是:
!>&&>||,没有例外 - 团队协作中,哪怕你确定自己没写错,也建议加括号。可读性损耗远小于一次线上逻辑 bug
赋值运算符 = 的优先级低到什么程度?
= 是 Go 中优先级最低的运算符之一,仅高于逗号操作符(但 Go 根本没逗号表达式)。这意味着几乎所有其他运算都会先完成,再赋值。比如 a = b + c * d 先算 c * d,再加 b,最后赋给 a。
容易踩的坑:在 if 条件里顺手写赋值,比如 if a = b { ... } —— 这根本不是比较,而是语法错误:syntax error: unexpected =, expecting ==。Go 强制区分 =(赋值)和 ==(比较),且不允许在 if 中直接赋值(不像 C)。
- 想在 if 中赋值并判断,得用短变量声明:
if v := getValue(); v > 0 { ... } -
+=、-=等复合赋值符,优先级和=完全相同,不是更高 - 函数调用
f()、切片索引a[i]、结构体字段s.f的优先级都比=高,所以a[i] = f() + s.f没歧义
真正复杂的地方从来不是“记不住哪条优先级高”,而是当表达式跨三行、嵌套两层、还混着类型转换时,括号加在哪、加不加,决定了别人读你代码时是点头还是皱眉。










