Go 运算符
目录
运算符是编程语言中用于执行操作的基本符号。Go 提供了丰富的运算符,包括算术、关系、逻辑、位运算和赋值运算符。本篇将逐一介绍各类运算符的用法,并配以代码示例。
算术运算符
Go 支持以下算术运算符:
| 运算符 | 说明 | 示例 |
|---|---|---|
+ |
加法 | a + b |
- |
减法 | a - b |
* |
乘法 | a * b |
/ |
除法 | a / b |
% |
取余 | a % b |
++ |
自增 | a++ |
-- |
自减 | a-- |
基本运算
package main
import "fmt"
func main() {
a, b := 17, 5
fmt.Println("a + b =", a+b) // 22
fmt.Println("a - b =", a-b) // 12
fmt.Println("a * b =", a*b) // 85
fmt.Println("a / b =", a/b) // 3(整数除法,截断小数部分)
fmt.Println("a %% b =", a%b) // 2(取余)
}整数除法与浮点除法
package main
import "fmt"
func main() {
// 整数除法会截断
fmt.Println("10 / 3 =", 10/3) // 3
fmt.Println("10 %% 3 =", 10%3) // 1
// 浮点除法保留小数
fmt.Println("10.0 / 3.0 =", 10.0/3.0) // 3.3333333333333335
}自增与自减
Go 中的 ++ 和 -- 是语句而非表达式,只能作为独立语句使用,不能放在表达式中:
package main
import "fmt"
func main() {
x := 10
x++ // 等价于 x = x + 1
fmt.Println("x++ 后:", x) // 11
x-- // 等价于 x = x - 1
fmt.Println("x-- 后:", x) // 10
// 以下写法在 Go 中是非法的:
// y := x++ // 编译错误
// fmt.Println(x++) // 编译错误
}关系运算符
关系运算符用于比较两个值,结果为布尔类型(true 或 false)。
| 运算符 | 说明 | 示例 |
|---|---|---|
== |
等于 | a == b |
!= |
不等于 | a != b |
< |
小于 | a < b |
> |
大于 | a > b |
<= |
小于等于 | a <= b |
>= |
大于等于 | a >= b |
package main
import "fmt"
func main() {
a, b := 10, 20
fmt.Println("a == b:", a == b) // false
fmt.Println("a != b:", a != b) // true
fmt.Println("a < b:", a < b) // true
fmt.Println("a > b:", a > b) // false
fmt.Println("a <= b:", a <= b) // true
fmt.Println("a >= b:", a >= b) // false
// 字符串也可以比较(按字典序)
s1, s2 := "apple", "banana"
fmt.Println("s1 < s2:", s1 < s2) // true
fmt.Println("s1 == s2:", s1 == s2) // false
}逻辑运算符
逻辑运算符用于组合布尔表达式:
| 运算符 | 说明 | 示例 |
|---|---|---|
&& |
逻辑与(短路求值) | a && b |
|| |
逻辑或(短路求值) | a || b |
! |
逻辑非 | !a |
短路求值
&& 和 || 具有短路特性:如果第一个操作数已经能确定结果,就不会计算第二个操作数。
package main
import "fmt"
func main() {
a, b := true, false
fmt.Println("a && b:", a && b) // false
fmt.Println("a || b:", a || b) // true
fmt.Println("!a:", !a) // false
// 短路求值的实际应用
age := 20
hasID := true
// 如果 hasID 为 false,不会检查 age
if hasID && age >= 18 {
fmt.Println("允许进入")
}
// 空指针保护
var name *string
if name != nil && *name != "" {
fmt.Println("名字:", *name)
} else {
fmt.Println("名字为空")
}
}位运算符
位运算符直接操作整数的二进制位:
| 运算符 | 说明 | 示例 |
|---|---|---|
& |
按位与 | a & b |
| |
按位或 | a | b |
^ |
按位异或 | a ^ b |
&^ |
按位清除(AND NOT) | a &^ b |
<< |
左移 | a << n |
>> |
右移 | a >> n |
基本位运算
package main
import "fmt"
func main() {
a := 12 // 二进制: 1100
b := 10 // 二进制: 1010
fmt.Printf("a & b = %d (二进制: %04b)\n", a&b, a&b) // 8, 1000
fmt.Printf("a | b = %d (二进制: %04b)\n", a|b, a|b) // 14, 1110
fmt.Printf("a ^ b = %d (二进制: %04b)\n", a^b, a^b) // 6, 0110
fmt.Printf("a &^ b = %d (二进制: %04b)\n", a&^b, a&^b) // 4, 0100
}位移运算
package main
import "fmt"
func main() {
x := 8 // 二进制: 1000
fmt.Printf("x << 1 = %d (二进制: %04b)\n", x<<1, x<<1) // 16, 10000
fmt.Printf("x << 2 = %d (二进制: %04b)\n", x<<2, x<<2) // 32, 100000
fmt.Printf("x >> 1 = %d (二进制: %04b)\n", x>>1, x>>1) // 4, 0100
fmt.Printf("x >> 2 = %d (二进制: %04b)\n", x>>2, x>>2) // 2, 0010
}位运算的实际应用
package main
import "fmt"
func main() {
// 判断奇偶
n := 7
if n&1 == 1 {
fmt.Println(n, "是奇数")
}
// 用位运算实现权限标志
const (
Read = 1 << iota // 1 (001)
Write // 2 (010)
Execute // 4 (100)
)
// 设置权限
perm := Read | Write // 011
fmt.Printf("当前权限: %03b\n", perm)
// 检查是否有某个权限
if perm&Read != 0 {
fmt.Println("有读权限")
}
if perm&Execute == 0 {
fmt.Println("没有执行权限")
}
// 添加权限
perm |= Execute
fmt.Printf("添加执行权限后: %03b\n", perm)
// 移除权限
perm &^= Write
fmt.Printf("移除写权限后: %03b\n", perm)
}赋值运算符
| 运算符 | 说明 | 等价写法 |
|---|---|---|
= |
赋值 | a = b |
+= |
加后赋值 | a = a + b |
-= |
减后赋值 | a = a - b |
*= |
乘后赋值 | a = a * b |
/= |
除后赋值 | a = a / b |
%= |
取余后赋值 | a = a % b |
&= |
按位与后赋值 | a = a & b |
|= |
按位或后赋值 | a = a | b |
^= |
按位异或后赋值 | a = a ^ b |
<<= |
左移后赋值 | a = a << b |
>>= |
右移后赋值 | a = a >> b |
package main
import "fmt"
func main() {
x := 100
x += 10 // x = x + 10
fmt.Println("+= 10:", x) // 110
x -= 30 // x = x - 30
fmt.Println("-= 30:", x) // 80
x *= 2 // x = x * 2
fmt.Println("*= 2:", x) // 160
x /= 4 // x = x / 4
fmt.Println("/= 4:", x) // 40
x %= 7 // x = x % 7
fmt.Println("%%= 7:", x) // 5
}运算符优先级
从高到低排列:
| 优先级 | 运算符 |
|---|---|
| 5(最高) | *, /, %, <<, >>, &, &^ |
| 4 | +, -, |, ^ |
| 3 | ==, !=, <, <=, >, >= |
| 2 | && |
| 1(最低) | || |
优先级示例
package main
import "fmt"
func main() {
// 乘除优先于加减
a := 2 + 3*4 // 2 + 12 = 14
fmt.Println("2+3*4 =", a)
// 关系运算符优先于逻辑运算符
b := 10 > 5 && 3 < 7 // (10>5) && (3<7) → true && true → true
fmt.Println("10>5 && 3<7 =", b)
// 使用括号提高可读性
c := (2 + 3) * 4 // 5 * 4 = 20
fmt.Println("(2+3)*4 =", c)
}建议:当表达式涉及多个运算符时,尽量使用括号明确优先级,提高代码可读性。
总结
本篇介绍了 Go 语言中的各类运算符。算术运算符用于数学计算,关系运算符用于比较,逻辑运算符用于组合布尔条件(支持短路求值),位运算符直接操作二进制位(常用于权限控制和底层优化),赋值运算符提供了简洁的复合赋值方式。理解运算符的优先级有助于避免逻辑错误,但更推荐的做法是使用括号让表达式的意图更加清晰。