Files
golang/golang-learning/01-basics/05-operators.go
2025-08-24 01:01:26 +08:00

475 lines
14 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
05-operators.go - Go 语言运算符详解
学习目标:
1. 掌握算术运算符的使用
2. 理解比较运算符的规则
3. 学会逻辑运算符的应用
4. 了解位运算符的用法
5. 掌握赋值运算符的使用
6. 理解运算符的优先级
知识点:
- 算术运算符 (+, -, *, /, %, ++, --)
- 比较运算符 (==, !=, <, <=, >, >=)
- 逻辑运算符 (&&, ||, !)
- 位运算符 (&, |, ^, <<, >>)
- 赋值运算符 (=, +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=)
- 其他运算符 (&, *, <-)
- 运算符优先级
*/
package main
import "fmt"
func main() {
fmt.Println("=== Go 语言运算符详解 ===\n")
// 演示算术运算符
demonstrateArithmeticOperators()
// 演示比较运算符
demonstrateComparisonOperators()
// 演示逻辑运算符
demonstrateLogicalOperators()
// 演示位运算符
demonstrateBitwiseOperators()
// 演示赋值运算符
demonstrateAssignmentOperators()
// 演示其他运算符
demonstrateOtherOperators()
// 演示运算符优先级
demonstrateOperatorPrecedence()
// 演示实际应用示例
demonstratePracticalExamples()
}
// demonstrateArithmeticOperators 演示算术运算符
func demonstrateArithmeticOperators() {
fmt.Println("1. 算术运算符:")
a, b := 15, 4
fmt.Printf(" 基本算术运算 (a=%d, b=%d):\n", a, b)
fmt.Printf(" a + b = %d + %d = %d\n", a, b, a+b)
fmt.Printf(" a - b = %d - %d = %d\n", a, b, a-b)
fmt.Printf(" a * b = %d * %d = %d\n", a, b, a*b)
fmt.Printf(" a / b = %d / %d = %d\n", a, b, a/b) // 整数除法
fmt.Printf(" a %% b = %d %% %d = %d\n", a, b, a%b) // 取余
// 浮点数除法
fa, fb := 15.0, 4.0
fmt.Printf(" 浮点数除法:\n")
fmt.Printf(" %.1f / %.1f = %.2f\n", fa, fb, fa/fb)
// 自增和自减运算符
fmt.Printf(" 自增和自减运算符:\n")
x := 10
fmt.Printf(" x = %d\n", x)
x++ // x = x + 1
fmt.Printf(" x++ 后: %d\n", x)
x-- // x = x - 1
fmt.Printf(" x-- 后: %d\n", x)
// 注意Go 中的 ++ 和 -- 是语句,不是表达式
fmt.Printf(" 注意: Go 中 ++ 和 -- 是语句,不能用在表达式中\n")
// y := x++ // 编译错误
// z := ++x // 编译错误Go 没有前置 ++
// 一元运算符
fmt.Printf(" 一元运算符:\n")
positive := +10
negative := -10
fmt.Printf(" +10 = %d\n", positive)
fmt.Printf(" -10 = %d\n", negative)
fmt.Println()
}
// demonstrateComparisonOperators 演示比较运算符
func demonstrateComparisonOperators() {
fmt.Println("2. 比较运算符:")
a, b := 10, 20
fmt.Printf(" 数值比较 (a=%d, b=%d):\n", a, b)
fmt.Printf(" a == b: %d == %d = %t\n", a, b, a == b)
fmt.Printf(" a != b: %d != %d = %t\n", a, b, a != b)
fmt.Printf(" a < b: %d < %d = %t\n", a, b, a < b)
fmt.Printf(" a <= b: %d <= %d = %t\n", a, b, a <= b)
fmt.Printf(" a > b: %d > %d = %t\n", a, b, a > b)
fmt.Printf(" a >= b: %d >= %d = %t\n", a, b, a >= b)
// 字符串比较
s1, s2 := "apple", "banana"
fmt.Printf(" 字符串比较 (s1=\"%s\", s2=\"%s\"):\n", s1, s2)
fmt.Printf(" s1 == s2: %t\n", s1 == s2)
fmt.Printf(" s1 < s2: %t (按字典序)\n", s1 < s2)
fmt.Printf(" s1 > s2: %t\n", s1 > s2)
// 布尔值比较
bool1, bool2 := true, false
fmt.Printf(" 布尔值比较:\n")
fmt.Printf(" true == false: %t\n", bool1 == bool2)
fmt.Printf(" true != false: %t\n", bool1 != bool2)
// 注意:不同类型不能直接比较
fmt.Printf(" 注意: 不同类型不能直接比较,需要类型转换\n")
var i int = 10
var f float64 = 10.0
// fmt.Println(i == f) // 编译错误
fmt.Printf(" int(10) == float64(10.0): %t\n", float64(i) == f)
fmt.Println()
}
// demonstrateLogicalOperators 演示逻辑运算符
func demonstrateLogicalOperators() {
fmt.Println("3. 逻辑运算符:")
a, b := true, false
fmt.Printf(" 基本逻辑运算 (a=%t, b=%t):\n", a, b)
fmt.Printf(" a && b: %t && %t = %t (逻辑与)\n", a, b, a && b)
fmt.Printf(" a || b: %t || %t = %t (逻辑或)\n", a, b, a || b)
fmt.Printf(" !a: !%t = %t (逻辑非)\n", a, !a)
fmt.Printf(" !b: !%t = %t\n", b, !b)
// 真值表
fmt.Printf(" 逻辑运算真值表:\n")
fmt.Printf(" A | B | A&&B | A||B | !A\n")
fmt.Printf(" ------|-------|-------|-------|------\n")
fmt.Printf(" true | true | %t | %t | %t\n", true && true, true || true, !true)
fmt.Printf(" true | false | %t| %t | %t\n", true && false, true || false, !true)
fmt.Printf(" false | true | %t| %t | %t\n", false && true, false || true, !false)
fmt.Printf(" false | false | %t| %t | %t\n", false && false, false || false, !false)
// 短路求值
fmt.Printf(" 短路求值演示:\n")
x, y := 5, 0
// && 短路:如果左边是 false右边不会执行
fmt.Printf(" 短路与: (x > 10) && (y != 0)\n")
result1 := (x > 10) && (y != 0)
fmt.Printf(" 结果: %t (右边条件不会被检查)\n", result1)
// || 短路:如果左边是 true右边不会执行
fmt.Printf(" 短路或: (x > 0) || (y != 0)\n")
result2 := (x > 0) || (y != 0)
fmt.Printf(" 结果: %t (右边条件不会被检查)\n", result2)
// 复合逻辑表达式
age := 25
hasLicense := true
hasInsurance := false
canDrive := age >= 18 && hasLicense && hasInsurance
fmt.Printf(" 复合条件判断:\n")
fmt.Printf(" 年龄: %d, 有驾照: %t, 有保险: %t\n", age, hasLicense, hasInsurance)
fmt.Printf(" 可以开车: %t\n", canDrive)
fmt.Println()
}
// demonstrateBitwiseOperators 演示位运算符
func demonstrateBitwiseOperators() {
fmt.Println("4. 位运算符:")
a, b := 12, 10 // 12 = 1100, 10 = 1010 (二进制)
fmt.Printf(" 位运算 (a=%d, b=%d):\n", a, b)
fmt.Printf(" a 的二进制: %08b\n", a)
fmt.Printf(" b 的二进制: %08b\n", b)
fmt.Printf(" a & b: %08b = %d (按位与)\n", a & b, a & b)
fmt.Printf(" a | b: %08b = %d (按位或)\n", a | b, a | b)
fmt.Printf(" a ^ b: %08b = %d (按位异或)\n", a ^ b, a ^ b)
fmt.Printf(" ^a: %08b = %d (按位取反)\n", ^a, ^a)
// 位移运算
fmt.Printf(" 位移运算:\n")
x := 8 // 1000 (二进制)
fmt.Printf(" x = %d (%08b)\n", x, x)
fmt.Printf(" x << 1: %08b = %d (左移1位)\n", x << 1, x << 1)
fmt.Printf(" x << 2: %08b = %d (左移2位)\n", x << 2, x << 2)
fmt.Printf(" x >> 1: %08b = %d (右移1位)\n", x >> 1, x >> 1)
fmt.Printf(" x >> 2: %08b = %d (右移2位)\n", x >> 2, x >> 2)
// 位运算的实际应用
fmt.Printf(" 位运算应用示例:\n")
// 检查奇偶性
num := 15
isEven := (num & 1) == 0
fmt.Printf(" %d 是偶数: %t (使用 n&1==0 检查)\n", num, isEven)
// 快速乘除法2的幂
fmt.Printf(" 快速乘除法:\n")
fmt.Printf(" %d * 4 = %d << 2 = %d\n", num, num, num << 2)
fmt.Printf(" %d / 4 = %d >> 2 = %d\n", num, num, num >> 2)
// 设置、清除、切换位
flags := 0
fmt.Printf(" 位标志操作:\n")
fmt.Printf(" 初始标志: %08b\n", flags)
flags |= (1 << 2) // 设置第2位
fmt.Printf(" 设置第2位: %08b\n", flags)
flags &^= (1 << 2) // 清除第2位
fmt.Printf(" 清除第2位: %08b\n", flags)
flags ^= (1 << 1) // 切换第1位
fmt.Printf(" 切换第1位: %08b\n", flags)
fmt.Println()
}
// demonstrateAssignmentOperators 演示赋值运算符
func demonstrateAssignmentOperators() {
fmt.Println("5. 赋值运算符:")
// 基本赋值
var x int = 10
fmt.Printf(" 基本赋值: x = %d\n", x)
// 复合赋值运算符
fmt.Printf(" 复合赋值运算符:\n")
x += 5 // x = x + 5
fmt.Printf(" x += 5: x = %d\n", x)
x -= 3 // x = x - 3
fmt.Printf(" x -= 3: x = %d\n", x)
x *= 2 // x = x * 2
fmt.Printf(" x *= 2: x = %d\n", x)
x /= 4 // x = x / 4
fmt.Printf(" x /= 4: x = %d\n", x)
x %= 3 // x = x % 3
fmt.Printf(" x %%= 3: x = %d\n", x)
// 位运算赋值
fmt.Printf(" 位运算赋值:\n")
y := 12 // 1100
fmt.Printf(" y = %d (%04b)\n", y, y)
y &= 10 // y = y & 10 (1010)
fmt.Printf(" y &= 10: y = %d (%04b)\n", y, y)
y |= 5 // y = y | 5 (0101)
fmt.Printf(" y |= 5: y = %d (%04b)\n", y, y)
y ^= 3 // y = y ^ 3 (0011)
fmt.Printf(" y ^= 3: y = %d (%04b)\n", y, y)
y <<= 1 // y = y << 1
fmt.Printf(" y <<= 1: y = %d (%04b)\n", y, y)
y >>= 2 // y = y >> 2
fmt.Printf(" y >>= 2: y = %d (%04b)\n", y, y)
// 多重赋值
fmt.Printf(" 多重赋值:\n")
a, b, c := 1, 2, 3
fmt.Printf(" a, b, c := 1, 2, 3: a=%d, b=%d, c=%d\n", a, b, c)
// 交换变量
a, b = b, a
fmt.Printf(" a, b = b, a: a=%d, b=%d (交换)\n", a, b)
fmt.Println()
}
// demonstrateOtherOperators 演示其他运算符
func demonstrateOtherOperators() {
fmt.Println("6. 其他运算符:")
// 地址运算符 &
x := 42
ptr := &x
fmt.Printf(" 地址运算符 &:\n")
fmt.Printf(" x = %d\n", x)
fmt.Printf(" &x = %p (x的地址)\n", ptr)
// 解引用运算符 *
fmt.Printf(" 解引用运算符 *:\n")
fmt.Printf(" *ptr = %d (ptr指向的值)\n", *ptr)
// 修改指针指向的值
*ptr = 100
fmt.Printf(" 修改 *ptr = 100 后, x = %d\n", x)
// 通道运算符 <- (这里只是语法演示,详细内容在并发章节)
fmt.Printf(" 通道运算符 <- (语法演示):\n")
ch := make(chan int, 1)
ch <- 42 // 发送值到通道
value := <-ch // 从通道接收值
fmt.Printf(" 通道发送和接收: %d\n", value)
fmt.Println()
}
// demonstrateOperatorPrecedence 演示运算符优先级
func demonstrateOperatorPrecedence() {
fmt.Println("7. 运算符优先级:")
// 算术运算符优先级
result1 := 2 + 3 * 4
result2 := (2 + 3) * 4
fmt.Printf(" 算术运算优先级:\n")
fmt.Printf(" 2 + 3 * 4 = %d (乘法优先)\n", result1)
fmt.Printf(" (2 + 3) * 4 = %d (括号改变优先级)\n", result2)
// 比较和逻辑运算符优先级
a, b, c := 5, 10, 15
result3 := a < b && b < c
result4 := a < b || b > c && c > a
fmt.Printf(" 比较和逻辑运算优先级:\n")
fmt.Printf(" %d < %d && %d < %d = %t\n", a, b, b, c, result3)
fmt.Printf(" %d < %d || %d > %d && %d > %d = %t\n", a, b, b, c, c, a, result4)
// 位运算符优先级
x := 6 // 110
y := 3 // 011
result5 := x & y | x ^ y
result6 := x & (y | x) ^ y
fmt.Printf(" 位运算优先级:\n")
fmt.Printf(" %d & %d | %d ^ %d = %d\n", x, y, x, y, result5)
fmt.Printf(" %d & (%d | %d) ^ %d = %d\n", x, y, x, y, result6)
// 运算符优先级表(从高到低)
fmt.Printf(" 运算符优先级表(从高到低):\n")
fmt.Printf(" 1. * / %% << >> & &^\n")
fmt.Printf(" 2. + - | ^\n")
fmt.Printf(" 3. == != < <= > >=\n")
fmt.Printf(" 4. &&\n")
fmt.Printf(" 5. ||\n")
fmt.Println()
}
// demonstratePracticalExamples 演示实际应用示例
func demonstratePracticalExamples() {
fmt.Println("8. 实际应用示例:")
// 示例1: 计算器功能
fmt.Printf(" 示例1 - 简单计算器:\n")
num1, num2 := 15.5, 4.2
operator := "+"
var result float64
switch operator {
case "+":
result = num1 + num2
case "-":
result = num1 - num2
case "*":
result = num1 * num2
case "/":
if num2 != 0 {
result = num1 / num2
} else {
fmt.Printf(" 错误: 除数不能为零\n")
return
}
}
fmt.Printf(" %.1f %s %.1f = %.2f\n", num1, operator, num2, result)
// 示例2: 判断闰年
fmt.Printf(" 示例2 - 判断闰年:\n")
year := 2024
isLeapYear := (year%4 == 0 && year%100 != 0) || (year%400 == 0)
fmt.Printf(" %d年是闰年: %t\n", year, isLeapYear)
// 示例3: 位掩码操作
fmt.Printf(" 示例3 - 权限系统 (位掩码):\n")
const (
READ = 1 << 0 // 001
WRITE = 1 << 1 // 010
EXECUTE = 1 << 2 // 100
)
// 设置权限
permissions := READ | WRITE // 011
fmt.Printf(" 初始权限: %03b (读:%t, 写:%t, 执行:%t)\n",
permissions,
permissions&READ != 0,
permissions&WRITE != 0,
permissions&EXECUTE != 0)
// 添加执行权限
permissions |= EXECUTE // 111
fmt.Printf(" 添加执行权限: %03b (读:%t, 写:%t, 执行:%t)\n",
permissions,
permissions&READ != 0,
permissions&WRITE != 0,
permissions&EXECUTE != 0)
// 移除写权限
permissions &^= WRITE // 101
fmt.Printf(" 移除写权限: %03b (读:%t, 写:%t, 执行:%t)\n",
permissions,
permissions&READ != 0,
permissions&WRITE != 0,
permissions&EXECUTE != 0)
// 示例4: 条件表达式模拟
fmt.Printf(" 示例4 - 条件表达式模拟:\n")
score := 85
var grade string
// Go 没有三元运算符,使用 if-else
if score >= 90 {
grade = "A"
} else if score >= 80 {
grade = "B"
} else if score >= 70 {
grade = "C"
} else if score >= 60 {
grade = "D"
} else {
grade = "F"
}
fmt.Printf(" 分数 %d 对应等级: %s\n", score, grade)
fmt.Println()
}
/*
运行这个程序:
go run 05-operators.go
学习要点:
1. Go 支持丰富的运算符,包括算术、比较、逻辑、位运算等
2. ++ 和 -- 在 Go 中是语句,不是表达式,不能用在赋值中
3. Go 不支持隐式类型转换,不同类型不能直接比较或运算
4. 逻辑运算符支持短路求值,可以提高效率和安全性
5. 位运算符在系统编程和性能优化中很有用
6. 复合赋值运算符可以简化代码
7. 运算符有优先级,使用括号可以改变优先级
8. Go 没有三元运算符,使用 if-else 代替
实际应用:
1. 算术运算符用于数学计算
2. 比较运算符用于条件判断
3. 逻辑运算符用于复合条件
4. 位运算符用于标志位操作、权限系统等
5. 赋值运算符用于变量更新
注意事项:
1. 除法运算要注意整数除法和浮点除法的区别
2. 取余运算的结果符号与被除数相同
3. 位运算时要注意数据类型的位数
4. 使用逻辑运算符时要注意短路求值的特性
5. 复杂表达式建议使用括号明确优先级
*/