【Go】P5 Go 语言基础:全面解析五大核心运算符
目录
- 1. 算术运算符 (Arithmetic Operators)
- 2. 关系运算符 (Relational Operators)
- 3. 逻辑运算符 (Logical Operators)
- 逻辑运算符的短路特性
- 4. 赋值运算符 (Assignment Operators)
- 5. 位运算符 (Bitwise Operators)
- 总结
在编程世界中,运算符是构建所有逻辑和计算的基础。对于 Go 语言这门以简洁、高效著称的语言来说,熟练掌握其运算符更是编写高质量代码的关键。Go 语言内置了丰富的运算符,我们可以将其分为五大类:算术运算符、关系运算符、逻辑运算符、赋值运算符和位运算符。
本文将带你深入探索这五类运算符,通过丰富的代码示例,让你彻底理解它们的用法和注意事项。
1. 算术运算符 (Arithmetic Operators)
算术运算符是我们编程中最常用到的,负责执行基本的数学运算,如:加、减、乘、除等。
运算符 | 名称 | 功能 |
---|---|---|
+ | 加 | 两数相加 |
- | 减 | 两数相减 |
* | 乘 | 两数相乘 |
/ | 除 | 两数相除 |
% | 取余 | 求除法的余数 |
代码示例:
package mainimport "fmt"func main() {a := 10b := 3// 加法fmt.Printf("a + b = %d\n", a+b) // 输出: a + b = 13// 减法fmt.Printf("a - b = %d\n", a-b) // 输出: a - b = 7// 乘法fmt.Printf("a * b = %d\n", a*b) // 输出: a * b = 30// 除法fmt.Printf("a / b = %d\n", a/b) // 输出: a / b = 3// 取余fmt.Printf("a % b = %d\n", a%b) // 输出: a % b = 1
}
重点注意:
- 整数除法: 在 Go 中,如果参与除法运算的两个数都是整数,那么结果也会是整数,小数部分会被自动舍弃。例如,
10 / 3
的结果是3
,而不是3.333...
。如果想得到精确的浮点数结果,至少需要将其中一个操作数转换为浮点类型。var x float64 = 10 var y int = 3 fmt.Println(x / float64(y)) // 输出: 3.3333333333333335
- 自增 (
++
) 和自减 (--
): 与 C++ 或 Java 不同,在 Go 语言中,++
和--
是独立的语句,而不是运算符,所以不支持自增/自减的同时完成赋值操作,且你不能将它们用在表达式中。此外,Go 只支持后置形式,即variable++
,不支持前置形式如++variable
。i := 5 i++ // 正确的用法:作为一条独立语句 fmt.Println(i) // 输出: 6j := i++ // 错误用法:不能在表达式中使用,会引发编译错误 fmt.Println(++i) // 错误用法:Go不支持前置自增/自减 }
2. 关系运算符 (Relational Operators)
关系运算符用于比较两个值之间的关系,其结果总是一个布尔值(true
或 false
)。这在流程控制(如 if 语句)中至关重要。
运算符 | 名称 | 功能 |
---|---|---|
== | 等于 | 检查两个值是否相等 |
!= | 不等于 | 检查两个值是否不相等 |
> | 大于 | 检查左值是否大于右值 |
< | 小于 | 检查左值是否小于右值 |
>= | 大于等于 | 检查左值是否大于或等于右值 |
<= | 小于等于 | 检查左值是否小于或等于右值 |
代码示例:
package mainimport "fmt"func main() {x := 10y := 20fmt.Println(x == y) // falsefmt.Println(x != y) // truefmt.Println(x > y) // falsefmt.Println(x < y) // truefmt.Println(x >= 10) // truefmt.Println(y <= 10) // false
}
3. 逻辑运算符 (Logical Operators)
逻辑运算符通常用于组合多个关系表达式,构建更复杂的条件判断。
运算符 | 名称 | 功能 |
---|---|---|
&& | 逻辑与 | 当所有条件都为 true 时,结果为 true |
|| | 逻辑或 | 当其中一个条件为 true 时,结果为 true |
! | 逻辑非 | 反转条件的布尔值,true 变为 false ,false 变为 true |
代码示例:
package mainimport "fmt"func main() {age := 25hasLicense := true// 场景1: 检查是否是成年且有驾照的司机if age >= 18 && hasLicense {fmt.Println("可以合法驾驶。")}// 场景2: 检查是否是儿童或老人(享受优惠)if age < 12 || age > 65 {fmt.Println("可以享受票价优惠。")}// 场景3: 逻辑非isTired := falseif !isTired {fmt.Println("精力充沛,继续工作!")}
}
逻辑运算符的短路特性
这是一个非常重要的特性,能有效提升代码性能。
- 逻辑与
&&
: 如果第一个条件为false
,Go 就不会再去判断第二个条件,因为最终结果已经确定为false
。 - 逻辑或
||
: 如果第一个条件为true
,Go 就不会再去判断第二个条件,因为最终结果已经确定为true
。
短路示例说明:
package mainimport "fmt"func checkAge(age int) bool {fmt.Println("正在检查年龄...")return age >= 18
}func hasCar() bool {fmt.Println("正在检查是否有车...")return true
}func main() {// 示例1: 逻辑与 && 短路fmt.Println("--- 逻辑与 && 短路测试 ---")// 因为 checkAge(15) 返回 false,所以 hasCar() 根本不会被调用if checkAge(15) && hasCar() {fmt.Println("条件满足")} else {fmt.Println("条件不满足")}// 输出:// --- 逻辑与 && 短路测试 ---// 正在检查年龄...// 条件不满足fmt.Println("\n--- 逻辑或 || 短路测试 ---")// 因为 checkAge(20) 返回 true,所以 hasCar() 根本不会被调用if checkAge(20) || hasCar() {fmt.Println("条件满足")}// 输出:// --- 逻辑或 || 短路测试 ---// 正在检查年龄...// 条件满足
}
利用短路特性,我们可以把成本较高检查置后,从而优化程序。
4. 赋值运算符 (Assignment Operators)
赋值运算符用于给变量分配一个值。最基本的是 =
,但 Go 提供了一套复合赋值运算符,让代码更简洁。
运算符 | 示例 | 等价于 |
---|---|---|
= | a = b | a = b |
+= | a += b | a = a + b |
-= | a -= b | a = a - b |
*= | a *= b | a = a * b |
/= | a /= b | a = a / b |
%= | a %= b | a = a % b |
代码示例:
package mainimport "fmt"func main() {var a int = 10a += 5 // a = 10 + 5fmt.Printf("a += 5 -> a = %d\n", a) // 输出: 15a -= 3 // a = 15 - 3fmt.Printf("a -= 3 -> a = %d\n", a) // 输出: 12a *= 2 // a = 12 * 2fmt.Printf("a *= 2 -> a = %d\n", a) // 输出: 24a /= 4 // a = 24 / 4fmt.Printf("a /= 4 -> a = %d\n", a) // 输出: 6a %= 5 // a = 6 % 5fmt.Printf("a %%= 5 -> a = %d\n", a) // 输出: 1
}
5. 位运算符 (Bitwise Operators)
位运算符直接对整数在内存中的二进制位进行操作。它们在处理底层数据、加密算法或性能要求极高的场景中非常有用。
运算符 | 名称 | 功能 |
---|---|---|
& | 按位与 | 两个操作数的对应位都为1时,结果位为1 |
| | 按位或 | 两个操作数的对应位有一个为1,结果位为1 |
^ | 按位异或 | 两个操作数的对应位不同时,结果位为1 |
<< | 左移 | 将所有位向左移动指定的位数 |
>> | 右移 | 将所有位向右移动指定的位数 |
代码示例:
假设 a = 5
(二进制 0101
),b = 3
(二进制 0011
)。
package mainimport "fmt"func main() {a := 5 // 0101b := 3 // 0011// 按位与: 0101 & 0011 = 0001 (十进制 1)fmt.Printf("a & b = %d (二进制: %b)\n", a&b, a&b)// 按位或: 0101 | 0011 = 0111 (十进制 7)fmt.Printf("a | b = %d (二进制: %b)\n", a|b, a|b)// 按位异或: 0101 ^ 0011 = 0110 (十进制 6)fmt.Printf("a ^ b = %d (二进制: %b)\n", a^b, a^b)// 左移: 5 << 1 (0101 << 1) = 1010 (十进制 10)// 左移 n 位相当于乘以 2 的 n 次方fmt.Printf("a << 1 = %d (二进制: %b)\n", a<<1, a<<1)// 右移: 5 >> 1 (0101 >> 1) = 0010 (十进制 2)// 右移 n 位相当于除以 2 的 n 次方fmt.Printf("a >> 1 = %d (二进制: %b)\n", a>>1, a>>1)
}
总结
掌握 Go 语言的这五种基本运算符是编写任何有效程序的基石。
- 算术运算符处理数值计算。
- 关系运算符用于比较,是条件判断的核心。
- 逻辑运算符组合多个条件,实现复杂逻辑,其短路特性值得关注。
- 赋值运算符让变量赋值和更新操作更简洁。
- 位运算符提供了对数据底层二进制表示的直接操控能力。
希望这篇详尽的指南和丰富的示例能帮助你更牢固地掌握 Go 语言的运算符。在实践中多多运用,你将能编写出更优雅、更高效的 Go 代码。
2025.10.15 金融街