运算符优先级 #

一、优先级概述 #

运算符优先级决定了表达式中运算的顺序。优先级高的运算符先执行。

二、优先级表 #

从高到低:

优先级 运算符 说明
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
}

十、总结 #

运算符优先级要点:

优先级(高→低) 运算符
最高 ! + - * & ^(单目)
* / % << >> & &^
+ - | ^
较低 == != < <= > >=
&&
最低 ||

关键点:

  1. 乘法优先:* / % 优先于 + -
  2. 比较优先:比较运算符优先于逻辑运算符
  3. 逻辑顺序:&& 优先于 ||
  4. 括号优先:使用括号明确计算顺序
  5. 可读性:复杂表达式使用括号或分解

准备好学习控制流了吗?让我们进入下一章!

最后更新:2026-03-26