Go 语言运算符
运算符是用于执行特定运算的符号。Go 语言提供了丰富的运算符,包括算术、比较、逻辑、位运算、赋值等运算符。本章将详细介绍各种运算符的使用方法和应用场景。
🧮 算术运算符
基本算术运算
go
package main
import "fmt"
func main() {
a, b := 15, 4
fmt.Printf("a = %d, b = %d\n", a, b)
fmt.Printf("加法: %d + %d = %d\n", a, b, a+b) // 19
fmt.Printf("减法: %d - %d = %d\n", a, b, a-b) // 11
fmt.Printf("乘法: %d * %d = %d\n", a, b, a*b) // 60
fmt.Printf("除法: %d / %d = %d\n", a, b, a/b) // 3 (整数除法)
fmt.Printf("取余: %d %% %d = %d\n", a, b, a%b) // 3
// 浮点数运算
x, y := 15.0, 4.0
fmt.Printf("\n浮点数运算:\n")
fmt.Printf("%.1f / %.1f = %.2f\n", x, y, x/y) // 3.75
// 一元运算符
fmt.Printf("\n一元运算符:\n")
fmt.Printf("+a = %d\n", +a) // 15 (正号)
fmt.Printf("-a = %d\n", -a) // -15 (负号)
}整数除法和取余
go
func main() {
// 整数除法(截断除法)
fmt.Println("整数除法:")
fmt.Printf("7 / 3 = %d\n", 7/3) // 2
fmt.Printf("7 / -3 = %d\n", 7/-3) // -2
fmt.Printf("-7 / 3 = %d\n", -7/3) // -2
fmt.Printf("-7 / -3 = %d\n", -7/-3) // 2
// 取余运算
fmt.Println("\n取余运算:")
fmt.Printf("7 %% 3 = %d\n", 7%3) // 1
fmt.Printf("7 %% -3 = %d\n", 7%-3) // 1
fmt.Printf("-7 %% 3 = %d\n", -7%3) // -1
fmt.Printf("-7 %% -3 = %d\n", -7%-3) // -1
// 应用:判断奇偶数
numbers := []int{1, 2, 3, 4, 5, 6}
for _, num := range numbers {
if num%2 == 0 {
fmt.Printf("%d 是偶数\n", num)
} else {
fmt.Printf("%d 是奇数\n", num)
}
}
}递增和递减运算符
go
func main() {
// 后置递增递减(Go 只有后置形式)
i := 5
fmt.Printf("初始值: i = %d\n", i)
i++ // 等价于 i = i + 1
fmt.Printf("i++ 后: i = %d\n", i) // 6
i-- // 等价于 i = i - 1
fmt.Printf("i-- 后: i = %d\n", i) // 5
// 注意:++ 和 -- 是语句,不是表达式
// x := i++ // 错误!不能这样使用
// y := ++i // 错误!Go 没有前置递增
// 正确的用法
j := i
i++
fmt.Printf("j = %d, i = %d\n", j, i)
// 在循环中的常见用法
fmt.Println("计数循环:")
for count := 0; count < 5; count++ {
fmt.Printf("计数: %d\n", count)
}
}⚖️ 比较运算符
基本比较运算
go
func main() {
a, b := 10, 20
fmt.Printf("a = %d, b = %d\n", a, b)
fmt.Printf("a == b: %t\n", a == b) // false (等于)
fmt.Printf("a != b: %t\n", a != b) // true (不等于)
fmt.Printf("a < b: %t\n", a < b) // true (小于)
fmt.Printf("a <= b: %t\n", a <= b) // true (小于等于)
fmt.Printf("a > b: %t\n", a > b) // false (大于)
fmt.Printf("a >= b: %t\n", a >= b) // false (大于等于)
// 字符串比较(字典序)
str1, str2 := "apple", "banana"
fmt.Printf("\n字符串比较:\n")
fmt.Printf("\"%s\" < \"%s\": %t\n", str1, str2, str1 < str2)
fmt.Printf("\"%s\" == \"%s\": %t\n", str1, str1, str1 == str1)
}不同类型的比较
go
import "math"
func main() {
// 浮点数比较需要注意精度问题
f1 := 0.1 + 0.2
f2 := 0.3
fmt.Printf("0.1 + 0.2 = %.17f\n", f1)
fmt.Printf("0.3 = %.17f\n", f2)
fmt.Printf("f1 == f2: %t\n", f1 == f2) // false!
// 浮点数比较的正确方法
epsilon := 1e-9
isEqual := math.Abs(f1-f2) < epsilon
fmt.Printf("使用精度比较: %t\n", isEqual) // true
// 特殊浮点值
fmt.Printf("\n特殊浮点值比较:\n")
fmt.Printf("NaN == NaN: %t\n", math.NaN() == math.NaN()) // false
fmt.Printf("Inf == Inf: %t\n", math.Inf(1) == math.Inf(1)) // true
// 布尔值比较
fmt.Printf("\n布尔值比较:\n")
fmt.Printf("true == true: %t\n", true == true) // true
fmt.Printf("true != false: %t\n", true != false) // true
}🧠 逻辑运算符
基本逻辑运算
go
func main() {
a, b := true, false
fmt.Printf("a = %t, b = %t\n", a, b)
fmt.Printf("a && b: %t\n", a && b) // false (逻辑与)
fmt.Printf("a || b: %t\n", a || b) // true (逻辑或)
fmt.Printf("!a: %t\n", !a) // false (逻辑非)
fmt.Printf("!b: %t\n", !b) // true (逻辑非)
// 复合逻辑表达式
x, y, z := true, false, true
result1 := x && y || z // (x && y) || z = false || true = true
result2 := x && (y || z) // x && (y || z) = true && true = true
fmt.Printf("\n复合表达式:\n")
fmt.Printf("x && y || z: %t\n", result1)
fmt.Printf("x && (y || z): %t\n", result2)
}短路求值
go
func main() {
// 逻辑与的短路求值
fmt.Println("逻辑与短路求值:")
if false && expensiveFunction() {
fmt.Println("不会执行")
}
// 逻辑或的短路求值
fmt.Println("逻辑或短路求值:")
if true || expensiveFunction() {
fmt.Println("会执行,但expensiveFunction不会被调用")
}
// 实际应用:安全检查
var ptr *int
if ptr != nil && *ptr > 0 {
fmt.Println("指针有效且值为正")
} else {
fmt.Println("指针为空或值不为正")
}
}
func expensiveFunction() bool {
fmt.Println("昂贵的函数被调用了")
return true
}🔢 位运算符
基本位运算
go
func main() {
a, b := uint8(60), uint8(13) // 60 = 0011 1100, 13 = 0000 1101
fmt.Printf("a = %d (二进制: %08b)\n", a, a)
fmt.Printf("b = %d (二进制: %08b)\n", b, b)
fmt.Printf("\n位运算结果:\n")
fmt.Printf("a & b = %d (二进制: %08b)\n", a&b, a&b) // 按位与: 12 = 0000 1100
fmt.Printf("a | b = %d (二进制: %08b)\n", a|b, a|b) // 按位或: 61 = 0011 1101
fmt.Printf("a ^ b = %d (二进制: %08b)\n", a^b, a^b) // 按位异或: 49 = 0011 0001
fmt.Printf("^a = %d (二进制: %08b)\n", ^a, ^a) // 按位取反: 195 = 1100 0011
// 位移运算
fmt.Printf("\n位移运算:\n")
fmt.Printf("a << 2 = %d (二进制: %08b)\n", a<<2, a<<2) // 左移: 240 = 1111 0000
fmt.Printf("a >> 2 = %d (二进制: %08b)\n", a>>2, a>>2) // 右移: 15 = 0000 1111
}位运算的应用
权限管理
go
func main() {
// 使用位标志表示权限
const (
PermissionRead = 1 << iota // 1 = 0001
PermissionWrite // 2 = 0010
PermissionExecute // 4 = 0100
PermissionDelete // 8 = 1000
)
// 设置权限
userPermissions := PermissionRead | PermissionWrite // 3 = 0011
fmt.Printf("用户权限: %d (二进制: %04b)\n", userPermissions, userPermissions)
// 检查权限
hasRead := userPermissions&PermissionRead != 0
hasWrite := userPermissions&PermissionWrite != 0
hasExecute := userPermissions&PermissionExecute != 0
hasDelete := userPermissions&PermissionDelete != 0
fmt.Printf("读权限: %t\n", hasRead)
fmt.Printf("写权限: %t\n", hasWrite)
fmt.Printf("执行权限: %t\n", hasExecute)
fmt.Printf("删除权限: %t\n", hasDelete)
// 添加权限
userPermissions |= PermissionExecute
fmt.Printf("添加执行权限后: %d (二进制: %04b)\n", userPermissions, userPermissions)
// 移除权限
userPermissions &^= PermissionWrite // 位清除运算符
fmt.Printf("移除写权限后: %d (二进制: %04b)\n", userPermissions, userPermissions)
}快速数学运算
go
func main() {
// 使用位运算进行快速计算
n := 16
// 判断是否为2的幂
isPowerOfTwo := n > 0 && (n&(n-1)) == 0
fmt.Printf("%d 是2的幂: %t\n", n, isPowerOfTwo)
// 乘以2的幂(左移)
fmt.Printf("%d * 4 = %d (使用 %d << 2)\n", n, n<<2, n)
fmt.Printf("%d * 8 = %d (使用 %d << 3)\n", n, n<<3, n)
// 除以2的幂(右移)
fmt.Printf("%d / 4 = %d (使用 %d >> 2)\n", n, n>>2, n)
fmt.Printf("%d / 8 = %d (使用 %d >> 3)\n", n, n>>3, n)
// 获取最低位的1
lowestBit := n & (-n)
fmt.Printf("%d 的最低位1: %d\n", n, lowestBit)
// 计算二进制中1的个数(Hamming重量)
count := popCount(uint(n))
fmt.Printf("%d 的二进制表示中1的个数: %d\n", n, count)
}
func popCount(x uint) int {
count := 0
for x != 0 {
count++
x &= x - 1 // 清除最低位的1
}
return count
}📝 赋值运算符
基本赋值
go
func main() {
var x int
// 基本赋值
x = 10
fmt.Printf("x = %d\n", x)
// 复合赋值运算符
x += 5 // x = x + 5
fmt.Printf("x += 5: %d\n", x) // 15
x -= 3 // x = x - 3
fmt.Printf("x -= 3: %d\n", x) // 12
x *= 2 // x = x * 2
fmt.Printf("x *= 2: %d\n", x) // 24
x /= 4 // x = x / 4
fmt.Printf("x /= 4: %d\n", x) // 6
x %= 5 // x = x % 5
fmt.Printf("x %%= 5: %d\n", x) // 1
}位运算赋值
go
func main() {
x := uint8(60) // 0011 1100
fmt.Printf("初始值 x = %d (二进制: %08b)\n", x, x)
x &= 15 // x = x & 15 (0000 1111)
fmt.Printf("x &= 15: %d (二进制: %08b)\n", x, x) // 12 (0000 1100)
x |= 3 // x = x | 3 (0000 0011)
fmt.Printf("x |= 3: %d (二进制: %08b)\n", x, x) // 15 (0000 1111)
x ^= 5 // x = x ^ 5 (0000 0101)
fmt.Printf("x ^= 5: %d (二进制: %08b)\n", x, x) // 10 (0000 1010)
x <<= 1 // x = x << 1
fmt.Printf("x <<= 1: %d (二进制: %08b)\n", x, x) // 20 (0001 0100)
x >>= 2 // x = x >> 2
fmt.Printf("x >>= 2: %d (二进制: %08b)\n", x, x) // 5 (0000 0101)
}多重赋值
go
func main() {
// 多重赋值
a, b, c := 1, 2, 3
fmt.Printf("初始值: a=%d, b=%d, c=%d\n", a, b, c)
// 交换变量
a, b = b, a
fmt.Printf("交换 a 和 b: a=%d, b=%d, c=%d\n", a, b, c)
// 函数返回多个值
x, y := divmod(17, 5)
fmt.Printf("17 除以 5: 商=%d, 余数=%d\n", x, y)
// 忽略某些值
quotient, _ := divmod(20, 3) // 忽略余数
fmt.Printf("20 除以 3 的商: %d\n", quotient)
// 批量赋值
var (
name string
age int
city string
)
name, age, city = "张三", 25, "北京"
fmt.Printf("个人信息: %s, %d岁, 来自%s\n", name, age, city)
}
func divmod(a, b int) (int, int) {
return a / b, a % b
}🎯 运算符优先级
优先级表
go
func main() {
// Go 运算符优先级(从高到低)
// 1. 最高优先级:一元运算符
x := 5
result1 := -x * 2 // -5 * 2 = -10
fmt.Printf("-x * 2 = %d\n", result1)
// 2. 乘除法、取余、位移、位与
result2 := 2 + 3 * 4 // 2 + 12 = 14
result3 := 8 << 1 + 1 // 8 << 2 = 32
result4 := 12 & 7 + 1 // 12 & 8 = 8
fmt.Printf("2 + 3 * 4 = %d\n", result2)
fmt.Printf("8 << 1 + 1 = %d\n", result3)
fmt.Printf("12 & 7 + 1 = %d\n", result4)
// 3. 加减法、位或、位异或
result5 := 1 + 2 << 3 // 1 + (2 << 3) = 1 + 16 = 17
result6 := 5 | 2 + 1 // 5 | 3 = 7
fmt.Printf("1 + 2 << 3 = %d\n", result5)
fmt.Printf("5 | 2 + 1 = %d\n", result6)
// 4. 比较运算符
result7 := 1 + 2 == 3 // true
result8 := 2 * 3 > 5 // true
fmt.Printf("1 + 2 == 3: %t\n", result7)
fmt.Printf("2 * 3 > 5: %t\n", result8)
// 5. 逻辑与
result9 := true && 2 > 1 // true
fmt.Printf("true && 2 > 1: %t\n", result9)
// 6. 逻辑或
result10 := false || 3 < 5 // true
fmt.Printf("false || 3 < 5: %t\n", result10)
}使用括号明确优先级
go
func main() {
// 不使用括号(依赖默认优先级)
result1 := 2 + 3 * 4 - 1 // 2 + 12 - 1 = 13
// 使用括号明确表达意图
result2 := (2 + 3) * (4 - 1) // 5 * 3 = 15
result3 := 2 + (3 * 4) - 1 // 与result1相同,但更清晰
fmt.Printf("默认优先级: 2 + 3 * 4 - 1 = %d\n", result1)
fmt.Printf("使用括号: (2 + 3) * (4 - 1) = %d\n", result2)
fmt.Printf("明确括号: 2 + (3 * 4) - 1 = %d\n", result3)
// 复杂表达式
a, b, c := 2, 3, 4
complex1 := a + b * c > 10 && a < b || c == 4
complex2 := ((a + (b * c)) > 10) && (a < b) || (c == 4)
fmt.Printf("复杂表达式1: %t\n", complex1)
fmt.Printf("复杂表达式2: %t\n", complex2)
}🎯 实际应用示例
数学计算器
go
import "fmt"
func main() {
// 简单计算器
calculator := NewCalculator()
// 基本运算
fmt.Printf("10 + 5 = %.2f\n", calculator.Add(10, 5))
fmt.Printf("10 - 5 = %.2f\n", calculator.Subtract(10, 5))
fmt.Printf("10 * 5 = %.2f\n", calculator.Multiply(10, 5))
fmt.Printf("10 / 5 = %.2f\n", calculator.Divide(10, 5))
// 高级运算
fmt.Printf("2^8 = %.0f\n", calculator.Power(2, 8))
fmt.Printf("√16 = %.2f\n", calculator.SquareRoot(16))
fmt.Printf("10%% = %.2f\n", calculator.Percentage(10))
}
type Calculator struct{}
func NewCalculator() *Calculator {
return &Calculator{}
}
func (c *Calculator) Add(a, b float64) float64 {
return a + b
}
func (c *Calculator) Subtract(a, b float64) float64 {
return a - b
}
func (c *Calculator) Multiply(a, b float64) float64 {
return a * b
}
func (c *Calculator) Divide(a, b float64) float64 {
if b == 0 {
panic("除数不能为零")
}
return a / b
}
func (c *Calculator) Power(base, exp float64) float64 {
result := 1.0
for i := 0; i < int(exp); i++ {
result *= base
}
return result
}
func (c *Calculator) SquareRoot(n float64) float64 {
if n < 0 {
panic("负数没有实数平方根")
}
// 牛顿法求平方根
x := n
for i := 0; i < 10; i++ {
x = (x + n/x) / 2
}
return x
}
func (c *Calculator) Percentage(n float64) float64 {
return n / 100
}🎓 小结
本章我们全面学习了 Go 语言的运算符:
- ✅ 算术运算符:+、-、*、/、%、++、--
- ✅ 比较运算符:==、!=、<、<=、>、>=
- ✅ 逻辑运算符:&&、||、!,短路求值
- ✅ 位运算符:&、|、^、<<、>>、&^
- ✅ 赋值运算符:=、+=、-=、*=、/=、%=等
- ✅ 运算符优先级:优先级规则和括号使用
掌握运算符的正确使用是编写高效 Go 代码的基础,特别是位运算符在系统编程和性能优化中有重要作用。
接下来,我们将学习 Go 语言条件语句,掌握程序的分支控制。
运算符使用建议
- 使用括号明确复杂表达式的运算顺序
- 注意浮点数比较的精度问题
- 利用位运算进行高效的标志位操作
- 善用短路求值提高程序性能