- 示例工程
- 教程
【免费下载链接】learngo
❤️ 1000+ Hand-Crafted Go Examples, Exercises, and Quizzes. 🚀 Learn Go by fixing 1000+ tiny programs.
导读
运算符优先级(Operator Precedence)决定了5 - 2 * 5 + 7这类表达式到底先算哪一步、结果是多少,是 Go 学习者最容易踩坑的基础知识之一。本文以 learngo 仓库中 运算符优先级问答题 的四道经典题目为主线,结合仓库内完整的可运行示例代码,逐一拆解优先级、结合性、括号改写与浮点/整数混合运算的完整规则。读完本文,你将能快速心算任何由*、/、%、+、-、一元负号与括号组成的 Go 算术表达式,并掌握用括号安全改写复杂公式的实战技巧。
一、优先级是什么:乘除先算,加减后算
在 Go 中,算术运算符按优先级分层,优先级高的先执行。对本文涉及的算术运算符,规则很简单:
- 一元运算符(如负号
-x)优先级最高; - 乘法类运算符
*、/、%次之; - 加法类运算符
+、-最低。
也就是说,遇到没有括号的表达式时,Go 会先做乘、除、取余,再做加、减。这直接决定了5 - 2 * 5 + 7的计算路径:
- 先算乘法:
2 * 5 = 10; - 再从左到右做加减:
5 - 10 + 7 = 2。
仓库中的示例 03-precedence/01/main.go 用可运行的代码演示了这一过程:
fmt.Println( 2+2*4/2, 2+((2*4)/2), // 括号显式标出实际计算顺序:先 * 后 / )两个表达式输出相同结果,因为2+2*4/2中*与/优先级相同,且都高于+,等价于2+((2*4)/2)。
二、原题逐解:四道优先级测验全解析
问答题 02-precedence.md 用四道层层递进的题目,覆盖了优先级、结合性与括号三大知识点。这里完整还原每题的计算过程。
题 1:5 - 2 * 5 + 7→ 结果2
- 优先级规则:
*先于-、+。 - 计算过程:
5 - (2*5) + 7→5 - 10 + 7→2。 - 干扰项分析:
22是把加法全部先算的错误结果;-19是把减法先于乘法的错误结果;36、-12均为不同错误顺序下的产物。
题 2:5 - (2 * 5) + 7→ 结果2
加上括号后,乘法2 * 5被显式括起来,但括号内本来就是优先级最高的部分,所以结果与题 1 完全一致,仍为2。原题提示指出:该表达式等价于5 + (2 * 5) + 7在数值上的另一种书写方式(即先算2*5=10,再做5-10+7)。
题 3:5 - 2 * (5 + 7)→ 结果-19
这里括号改变了计算顺序:(5 + 7)优先计算,然后乘法在减法之前执行:
5 + 7 = 122 * 12 = 245 - 24 = -19
这正是"括号可以覆盖默认优先级"的经典示范:同样的数字,仅仅改变括号位置,结果就从2变成了-19。
题 4:5. - (2 * 5 + 7)→ 结果-12.0
注意题干是5.(带小数点的浮点数),而非整数5。计算过程:
2 * 5 = 1010 + 7 = 175. - 17 = -12.0
原题特别指出:只要表达式中出现浮点数与整数的混合运算,结果就一定是浮点数。因此-12(整数写法)是错误的,-12.0才是正确答案。
三、同级运算符的结合性:从左到右
当优先级相同时,Go 按从左到右的结合性求值。仓库示例 03-precedence/01/main.go 同时演示了这一点:
fmt.Println( 1+4-2, (1+4)-2, // 等价:+ 和 - 同级,从左到右 )而 03-precedence/02/main.go 用变量展示了*与/的从左到右结合,以及括号如何改变顺序:
n, m := 1, 5 fmt.Println(2 + 1*m/n) fmt.Println(2 + ((1 * m) / n)) // 实际顺序:先 1*m,再 /n // 用括号强制改变顺序 fmt.Println(((2 + 1) * m) / n)同一组数字,2 + 1*m/n与((2+1) * m) / n的结果完全不同——前者等价于2 + ((1*5)/1) = 7,后者是(3*5)/1 = 15。这就是括号的威力。
四、括号的实战价值:华氏度转换公式
为什么括号不只是应付考试?看仓库示例 03-precedence/04/main.go,它用括号修正了一个典型的"公式陷阱":
celsius := 35. // 错误公式:9*celsius + 160 / 5 // 正确公式:(9*celsius + 160) / 5 fahrenheit := (9*celsius + 160) / 5 fmt.Printf("%g ºC is %g ºF\n", celsius, fahrenheit)若不使用括号,9*celsius + 160 / 5会按优先级先算160/5,再算乘法与加法,得到完全错误的温度值。而(9*celsius + 160) / 5保证了"分子整体"先求和、再整体除以 5。任何涉及公式移植的代码(如单位换算、物理计算、面积计算)都该养成"拿不准就加括号"的习惯。
03-precedence/03/main.go 的注释还给出了一个完整的推演示范,可以自行运行体会:
// 1 + 5 - 3*10/2 的计算顺序: // 3 * 10 = 30 // 30 / 2 = 15 // 1 + 5 = 6 // 6 - 15 = -9 // // 用括号改写为 (1 + 5 - 3) * (10 / 2) 后, // 先算 (1+5-3),再算 (10/2),结果完全不同五、浮点陷阱:优先级之外的精度问题
题 4 揭示了"浮点数参与运算则结果为浮点数"的规则,这与问答题 01-arithmetic-operators.md 中的内容互相印证:
var degree float64 = 10 / 4的结果是2而不是2.5,因为整数除法会丢弃小数部分;- 而
var degree float64 = 3. / 2的结果是1.5,因为3.使整个表达式成为浮点运算; x := 5 * 2.中x的类型是float64,同理x := 5 * -(2)中x的类型是int(全是整数)。
在此基础上还需警惕:浮点数本身存在精度误差。仓库示例 03-float-inaccuracy/01/main.go 用%.60f打印出1.0/10.0累加 10 次后的真实值,误差清晰可见。结合优先级与类型推导,才能写出结果符合预期的数值运算代码。
六、动手实践:优先级改写练习
仓库在 exercises/03-precedence/main.go 提供了一份"只用括号改变优先级、让每个表达式输出目标值"的练习,参考答案在 exercises/03-precedence/solution/main.go:
| 原表达式 | 目标输出 | 括号改写(参考答案) |
|---|---|---|
10 + 5 - 5 - 10 | 20 | 10 + 5 - (5 - 10) |
-10 + 0.5 - 1 + 5.5 | -16 | -10 + 0.5 - (1 + 5.5) |
5 + 10*2 - 5 | -25 | 5 + 10*(2-5) |
0.5*2 - 1 | 0.5 | 0.5 * (2 - 1) |
3 + 1/2*10 + 4 | 24 | (3+1)/2*10 + 4 |
10 / 2 * 10 % 7 | 15 | 10 / 2 * (10 % 7) |
100 / 5 / 2 | 40 | 100 / (5. / 2) |
建议先自行在 main.go 上尝试,再对照参考答案逐行推演。注意最后一行:100 / (5. / 2)中把5.写成浮点数后,5./2 = 2.5,100/2.5 = 40——若不这样做,100/5/2按整数除法从左到右得到的是10/2 = 5。它同时考察了优先级、结合性与浮点类型三个知识点,是整组练习中最有价值的一题。
七、小结:一张表记住 Go 算术优先级
| 优先级 | 运算符 | 结合性 | 说明 |
|---|---|---|---|
| 最高 | 一元-(负号)、+ | — | 作用于单个操作数 |
| 高 | *、/、% | 从左到右 | 乘法、除法、取余 |
| 低 | +、- | 从左到右 | 加法、减法 |
三条核心结论:
- 无括号时:先一元、再乘除取余、最后加减;同级从左到右;
- 有括号时:括号内最先计算,括号可以安全覆盖默认优先级,公式移植时"拿不准就加括号";
- 类型跟随:表达式中只要出现浮点字面量(如
5.、3.),结果就是浮点类型;整数除法丢弃小数部分。
掌握了优先级与括号,就能读懂仓库中任何一行算术代码,也能在编写单位换算、几何计算等公式类程序时避免隐蔽的逻辑错误。
- 示例工程
- 教程
【免费下载链接】learngo
❤️ 1000+ Hand-Crafted Go Examples, Exercises, and Quizzes. 🚀 Learn Go by fixing 1000+ tiny programs.
相关推荐
Mojo 运算符完全指南:从算术、位运算到优先级与赋值表达式的实战详解
Mojo 运算符完全指南:从算术、位运算到优先级与赋值表达式的实战详解 本文以 Mojo 官方手册 Operators https://link.gitcode
人工智能大模型编程语言编译器标准库算子库模型推理服务模型量化终极指南:掌握bash条件表达式优先级与括号运算符的完整攻略
终极指南:掌握bash条件表达式优先级与括号运算符的完整攻略 在bash脚本编程中,条件表达式和括号运算符是控制程序流程的核心工具。本指南将帮助你系统理解bas
教程Spark SQL 运算符(Operators)全解析:优先级、结合性与表达式求值原理
Spark SQL 运算符(Operators)全解析:优先级、结合性与表达式求值原理 SQL 运算符是作用于一个或多个表达式的符号,它决定了查询中复杂表达式的
大数据数据分析批处理流处理机器学习图计算
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考