

新闻资讯
技术学院Go 的 && 和 || 一定短路,因语言规范明确定义:&& 在左操作数为 false 时跳过右操作数,|| 在左操作数为 true 时跳过右操作数,运行时确定性生效,无例外。
Go 语言的 && 和 || 天然支持短路求值,不需要额外实现——只要写法合规,运行时自动生效。
&& 和 || 一定短路?这是 Go 语言规范明确定义的行为:&& 在左操作数为 false 时跳过右操作数;|| 在左操作数为 true 时跳过右操作数。底层不生成冗余调用,也无编译器开关可关闭。
f() || g() 中 f() 返回 true,则 g() 完全不调用)
发生在运行时,但属于确定性行为,和 CPU 分支预测无关开发者有时会依赖短路来控制函数执行顺序,例如:
if valid(id) && saveToCache(id) {
// ...
}
这种写法看似简洁,但有隐患:
saveToCache(id) 是业务逻辑,不是纯布尔判断,语义混淆bool,实际它还修改状态或触发 I/OsaveToCache 改为返回 error,整个表达式就编译失败saveToCache 失败路径,但被短路拦住了)用 if 块代替嵌套布尔表达式,可读性和可测性都更好:
if !valid(id) {
return
}
if err := saveToCache(id); err != nil {
log.Printf("cache save failed: %v", err)
return
}
// 后续逻辑
这种结构的优势:
ok, err := saveToCache(id); ok 这类变通staticcheck)更容易识别潜在 panic 或资源泄漏短路本身零开销,但若右操作数含局部变量构造(尤其是大结构体或切片),短路虽跳过执行,却可能让编译器无法优化其内存分配:
if cond {
// ...
} else if heavyComputation() > 0 { // heavyComputation 内部 new 了大 slice
// ...
}
此时即使 cond 为 true,heavyComputation 不调用,但它的栈帧布局仍可能影响外层函数的逃逸判定。真正影响性能的是函数内部实现,不是短路机制本身。
复杂点在于:短路是可靠的,但人容易把它当成控制流工具来用——而 Go 的控制流应该由 if/return 显式表达,不是靠布尔运算符的副作用隐式承载。