运算符用于在表达式中对操作数执行特定的运算。Go语言提供了丰富的运算符,包括算术、关系、逻辑、位运算、赋值、指针运算符等,以及用于运算优先级控制的括号。本章将完整介绍所有运算符的用法,并通过示例展示表达式求值过程。
用于执行基本的数学运算。支持整数和浮点数。
| 运算符 | 描述 | 示例 |
|---|---|---|
| + | 加法 | a + b |
| - | 减法 | a - b |
| * | 乘法 | a * b |
| / | 除法 | a / b(整数除法结果截断向零) |
| % | 取模(仅整数) | a % b(结果符号与被除数相同) |
package main
import "fmt"
func main() {
a, b := 10, 3
fmt.Println("a + b =", a+b) // 13
fmt.Println("a - b =", a-b) // 7
fmt.Println("a * b =", a*b) // 30
fmt.Println("a / b =", a/b) // 3(整数除法)
fmt.Println("a % b =", a%b) // 1
// 浮点数除法
x, y := 10.0, 3.0
fmt.Println("x / y =", x/y) // 3.3333333333333335
}
比较两个值,返回布尔值 true 或 false。支持所有基本类型(字符串按字典序比较)。
| 运算符 | 描述 | 示例 |
|---|---|---|
| == | 相等 | a == b |
| != | 不等 | a != b |
| < | 小于 | a < b |
| <= | 小于等于 | a <= b |
| > | 大于 | a > b |
| >= | 大于等于 | a >= b |
fmt.Println(5 == 5) // true
fmt.Println(5 != 6) // true
fmt.Println("go" < "go语言") // true (按字节比较)
仅用于布尔值,短路求值。
| 运算符 | 描述 | 示例 |
|---|---|---|
| && | 逻辑与 | a && b(若a为false则不计算b) |
| || | 逻辑或 | a || b(若a为true则不计算b) |
| ! | 逻辑非 | !a |
age := 25
if age > 18 && age < 60 {
fmt.Println("符合工作年龄")
}
直接操作整数的二进制位,支持整型(int, uint等)。
| 运算符 | 描述 | 示例 |
|---|---|---|
| & | 按位与 | a & b |
| | | 按位或 | a | b |
| ^ | 按位异或(也作一元取反) | a ^ b,^a(取反) |
| &^ | 位清空(AND NOT) | a &^ b(将a中b为1的位清零) |
| << | 左移 | a << n |
| >> | 右移 | a >> n |
a := 0b1100 // 12
b := 0b1010 // 10
fmt.Printf("a & b = %b\n", a & b) // 1000 (8)
fmt.Printf("a | b = %b\n", a | b) // 1110 (14)
fmt.Printf("a ^ b = %b\n", a ^ b) // 0110 (6)
fmt.Printf("a &^ b = %b\n", a &^ b) // 0100 (4)
fmt.Printf("a << 2 = %d\n", a << 2) // 48
fmt.Printf("a >> 1 = %d\n", a >> 1) // 6
// 一元取反(对uint类型)
c := uint8(1) // 00000001
fmt.Printf("^c = %b\n", ^c) // 11111110 (254)
将右侧表达式的值赋给左侧的左值。支持复合赋值。
| 运算符 | 描述 | 示例 |
|---|---|---|
| = | 赋值 | x = 10 |
| += | 加后赋值 | x += y => x = x + y |
| -= | 减后赋值 | x -= y |
| *= | 乘后赋值 | x *= y |
| /= | 除后赋值 | x /= y |
| %= | 取模后赋值 | x %= y |
| &= | 按位与后赋值 | x &= y |
| |= | 按位或后赋值 | x |= y |
| ^= | 按位异或后赋值 | x ^= y |
| &^= | 位清空后赋值 | x &^= y |
| <<= | 左移后赋值 | x <<= 2 |
| >>= | 右移后赋值 | x >>= 2 |
x := 100
ptr := &x // ptr 是 *int 类型
fmt.Println(*ptr) // 解引用,输出 100
*ptr = 200
fmt.Println(x) // 200
下表按照优先级从高到低排列。使用括号 () 可以显式改变运算顺序。
| 优先级 | 运算符 | 结合性 |
|---|---|---|
| 1(最高) | * / % << >> & &^ | 左结合 |
| 2 | + - | ^ | 左结合 |
| 3 | == != < <= > >= | 左结合 |
| 4 | && | 左结合 |
| 5(最低) | || | 左结合 |
一元运算符(如 !、^、*、&)优先级高于乘法类运算符,且是右结合。示例:
// 优先级示例
result := 1 + 2*3 // 7,等同于 1+(2*3)
fmt.Println(8 & 1<<2) // 0,因为 1<<2 先算,得到4,然后 8 & 4 = 0
package main
import "fmt"
func main() {
a, b, c := 15, 4, 6
// 算术和关系混合
result := a+b > c && a-b < c
fmt.Println(result) // true (19>6 && 11<6? 第二个是false, 故false)
// 实际执行:左侧 true,右侧 false,&& 结果为 false
// 位运算
x, y := 0x0F, 0x33
z := (x | y) & 0x0F
fmt.Printf("%#x\n", z) // 0x3
// 括号改变优先级
expr := 1 + 2*(3+4) // 1 + 2*7 = 15
fmt.Println(expr)
}
Go中的 ++ 和 -- 是语句而不是表达式,不能用于赋值给其他变量,且只能后缀。
count := 0
count++ // 正确,等同于 count += 1
// other = count++ // 编译错误:自增语句不返回值
// ++count // 编译错误:不支持前缀自增
package main
import "fmt"
func main() {
// 华氏度转摄氏度
f := 100.0
c := (f - 32) * 5 / 9
fmt.Printf("%.1f°F = %.1f°C\n", f, c)
// 使用位运算设置权限标志
const (
Read = 1 << iota // 1
Write // 2
Exec // 4
)
permissions := Read | Write // 3 (二进制 011)
// 检查是否具有Exec权限
if permissions & Exec == 0 {
fmt.Println("没有执行权限")
}
// 添加Exec权限
permissions |= Exec
fmt.Printf("新权限: %#b\n", permissions) // 111 = 7
}