/* 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. 复杂表达式建议使用括号明确优先级 */