运算符优先级 #
一、优先级概述 #
运算符优先级决定了表达式中运算的顺序。优先级高的运算符先执行。
二、优先级表 #
从高到低:
| 优先级 | 运算符 | 说明 |
|---|---|---|
| 1 | * / % << >> & &^ | 乘法类 |
| 2 | + - | ^ | 加法类 |
| 3 | == != < <= > >= | 比较类 |
| 4 | && | 逻辑与 |
| 5 | || | 逻辑或 |
注意:单目运算符(!、+、-、*、&、^)优先级最高。
三、结合性 #
3.1 左结合 #
大多数二元运算符是左结合的:
go
a - b - c // 等价于 (a - b) - c
a / b / c // 等价于 (a / b) / c
3.2 右结合 #
赋值运算符是右结合的:
go
a = b = c // Go不支持这种写法
四、示例解析 #
4.1 算术运算 #
go
result := 2 + 3 * 4
fmt.Println(result) // 14(先乘后加)
result = (2 + 3) * 4
fmt.Println(result) // 20(括号优先)
4.2 位运算与算术 #
go
a := 1 << 2 + 3
fmt.Println(a) // 16(1 << (2 + 3))
b := (1 << 2) + 3
fmt.Println(b) // 7
4.3 比较与逻辑 #
go
a := 5
b := 3
c := 2
result := a > b && b > c
fmt.Println(result) // true
result = a > b || b < c
fmt.Println(result) // true
4.4 复合表达式 #
go
a := 10
b := 5
c := 3
result := a + b*c > 20 && a-b < c
// 计算顺序:
// 1. b * c = 15
// 2. a + 15 = 25
// 3. a - b = 5
// 4. 25 > 20 = true
// 5. 5 < 3 = false
// 6. true && false = false
fmt.Println(result) // false
五、单目运算符 #
单目运算符优先级最高:
go
a := 5
b := -a + 3 // -a 先计算
fmt.Println(b) // -2
c := !true && false // !true 先计算
fmt.Println(c) // false
六、括号的使用 #
6.1 改变优先级 #
go
result := 2 + 3 * 4 // 14
result = (2 + 3) * 4 // 20
6.2 提高可读性 #
go
if (a > 0 && b > 0) || (c > 0 && d > 0) {
fmt.Println("条件满足")
}
6.3 避免歧义 #
go
result := a << 2 + 3 // 有歧义
result = a << (2 + 3) // 明确
result = (a << 2) + 3 // 明确
七、常见陷阱 #
7.1 位运算与比较 #
go
a := 1
b := 2
result := a & b == 0 // 错误:& 优先级低于 ==
result = (a & b) == 0 // 正确
7.2 逻辑运算优先级 #
go
a := true
b := false
c := true
result := a || b && c // a || (b && c) = true
fmt.Println(result)
result = (a || b) && c // true && true = true
fmt.Println(result)
7.3 移位与算术 #
go
a := 1
result := a << 2 + 3 // 1 << 5 = 32
result = (a << 2) + 3 // 4 + 3 = 7
八、最佳实践 #
8.1 使用括号 #
go
if (a > 0) && (b > 0) {
fmt.Println("都大于0")
}
8.2 分解复杂表达式 #
go
isAdult := age >= 18
hasLicense := license != nil
isDrunk := bloodAlcohol > 0
if isAdult && hasLicense && !isDrunk {
fmt.Println("可以驾驶")
}
8.3 避免过度依赖优先级 #
go
// 不推荐
result := a + b*c > d && e/f < g
// 推荐
sum := a + b*c
quotient := e / f
result := sum > d && quotient < g
九、完整示例 #
go
package main
import "fmt"
func main() {
a, b, c := 10, 5, 3
result1 := a + b*c
fmt.Println("a + b*c =", result1) // 25
result2 := (a + b) * c
fmt.Println("(a + b) * c =", result2) // 45
result3 := a > b && b > c
fmt.Println("a > b && b > c =", result3) // true
result4 := a > b || b < c
fmt.Println("a > b || b < c =", result4) // true
result5 := a & b | c
fmt.Println("a & b | c =", result5) // 11
result6 := a << 1 + 1
fmt.Println("a << 1 + 1 =", result6) // 40
result7 := (a << 1) + 1
fmt.Println("(a << 1) + 1 =", result7) // 21
}
十、总结 #
运算符优先级要点:
| 优先级(高→低) | 运算符 |
|---|---|
| 最高 | ! + - * & ^(单目) |
| 高 | * / % << >> & &^ |
| 中 | + - | ^ |
| 较低 | == != < <= > >= |
| 低 | && |
| 最低 | || |
关键点:
- 乘法优先:* / % 优先于 + -
- 比较优先:比较运算符优先于逻辑运算符
- 逻辑顺序:&& 优先于 ||
- 括号优先:使用括号明确计算顺序
- 可读性:复杂表达式使用括号或分解
准备好学习控制流了吗?让我们进入下一章!
最后更新:2026-03-26