2.3 运算符
2.3 运算符
运算符用于对变量和值执行操作。Go语言支持多种运算符,本节将详细介绍。
算术运算符
算术运算符用于执行数学运算。
| 运算符 | 描述 | 示例 |
|---|---|---|
| + | 加法 | a + b |
| - | 减法 | a - b |
| * | 乘法 | a * b |
| / | 除法 | a / b |
| % | 取模(余数) | a % b |
| ++ | 自增 | a++ |
| – | 自减 | a– |
示例
package main
import "fmt"
func main() {
a := 10
b := 3
fmt.Println("加法:", a+b) // 13
fmt.Println("减法:", a-b) // 7
fmt.Println("乘法:", a*b) // 30
fmt.Println("除法:", a/b) // 3 (整数除法)
fmt.Println("取模:", a%b) // 1
// 浮点除法
var x float64 = 10
var y float64 = 3
fmt.Printf("浮点除法: %.2f\n", x/y) // 3.33
// 自增自减
c := 5
c++
fmt.Println("自增后:", c) // 6
c--
fmt.Println("自减后:", c) // 5
}
注意:
-
++和--只能作为语句使用,不能用在表达式中 -
++和--只能后置,不能前置
// 正确
a++
a--
// 错误
++a // 编译错误
b = a++ // 编译错误
关系运算符
关系运算符用于比较两个值,返回布尔值。
| 运算符 | 描述 | 示例 |
|---|---|---|
| == | 等于 | a == b |
| != | 不等于 | a != b |
| > | 大于 | a > b |
| < | 小于 | a < b |
| >= | 大于等于 | a >= b |
| <= | 小于等于 | a <= b |
示例
package main
import "fmt"
func main() {
a := 10
b := 20
fmt.Println("a == b:", a == b) // false
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
fmt.Println("a <= b:", a <= b) // true
// 字符串比较
s1 := "abc"
s2 := "abc"
s3 := "xyz"
fmt.Println("s1 == s2:", s1 == s2) // true
fmt.Println("s1 == s3:", s1 == s3) // false
fmt.Println("s1 < s3:", s1 < s3) // true (字典序)
}
逻辑运算符
逻辑运算符用于组合布尔表达式。
| 运算符 | 描述 | 示例 |
|---|---|---|
| && | 逻辑与 | a && b |
| || | 逻辑或 | a || b |
| ! | 逻辑非 | !a |
示例
package main
import "fmt"
func main() {
a := true
b := false
fmt.Println("a && b:", a && b) // false
fmt.Println("a || b:", a || b) // true
fmt.Println("!a:", !a) // false
fmt.Println("!b:", !b) // true
// 短路求值
x := 10
y := 0
// && 短路:如果左边为false,右边不执行
if y != 0 && x/y > 5 {
fmt.Println("不会执行")
}
// || 短路:如果左边为true,右边不执行
if x > 5 || x/y > 5 {
fmt.Println("会执行,右边不会被计算")
}
}
位运算符
位运算符对整数的二进制位进行操作。
| 运算符 | 描述 | 示例 |
|---|---|---|
| & | 按位与 | a & b |
| | | 按位或 | a | b |
| ^ | 按位异或 | a ^ b |
| &^ | 按位清除 | a &^ b |
| << | 左移 | a << 2 |
| >> | 右移 | a >> 2 |
示例
package main
import "fmt"
func main() {
a := 60 // 0011 1100
b := 13 // 0000 1101
fmt.Printf("a & b = %d\n", a&b) // 12 (0000 1100)
fmt.Printf("a | b = %d\n", a|b) // 61 (0011 1101)
fmt.Printf("a ^ b = %d\n", a^b) // 49 (0011 0001)
fmt.Printf("a &^ b = %d\n", a&^b) // 48 (0011 0000)
// 移位运算
fmt.Printf("a << 2 = %d\n", a<<2) // 240 (左移2位)
fmt.Printf("a >> 2 = %d\n", a>>2) // 15 (右移2位)
// 实际应用:权限管理
const (
Read = 1 << 0 // 1 (0001)
Write = 1 << 1 // 2 (0010)
Execute = 1 << 2 // 4 (0100)
)
permission := Read | Write // 3 (0011)
fmt.Printf("权限值: %d\n", permission)
// 检查权限
hasRead := permission&Read != 0
hasExecute := permission&Execute != 0
fmt.Printf("有读权限: %t\n", hasRead) // true
fmt.Printf("有执行权限: %t\n", hasExecute) // false
}
赋值运算符
赋值运算符用于给变量赋值。
| 运算符 | 描述 | 示例 | 等价于 |
|---|---|---|---|
| = | 简单赋值 | a = b | a = b |
| += | 加后赋值 | a += b | a = a + b |
| -= | 减后赋值 | a -= b | a = a - b |
| *= | 乘后赋值 | a *= b | a = a * b |
| /= | 除后赋值 | a /= b | a = a / b |
| %= | 取模后赋值 | a %= b | a = a % b |
| &= | 按位与后赋值 | a &= b | a = a & b |
| |= | 按位或后赋值 | a |= b | a = a | b |
| ^= | 按位异或后赋值 | a ^= b | a = a ^ b |
| <<= | 左移后赋值 | a <<= 2 | a = a << 2 |
| >>= | 右移后赋值 | a >>= 2 | a = a >> 2 |
示例
package main
import "fmt"
func main() {
a := 10
a += 5
fmt.Println("a += 5:", a) // 15
a -= 3
fmt.Println("a -= 3:", a) // 12
a *= 2
fmt.Println("a *= 2:", a) // 24
a /= 4
fmt.Println("a /= 4:", a) // 6
a %= 4
fmt.Println("a %= 4:", a) // 2
// 位运算赋值
b := 8
b <<= 2
fmt.Println("b <<= 2:", b) // 32
}
其他运算符
取地址和取值运算符
| 运算符 | 描述 | 示例 |
|---|---|---|
| & | 取地址 | &a |
| * | 取值(解引用) | *p |
package main
import "fmt"
func main() {
a := 10
// 取地址
p := &a
fmt.Printf("a的地址: %p\n", p)
fmt.Printf("a的值: %d\n", a)
// 取值
fmt.Printf("p指向的值: %d\n", *p)
// 通过指针修改值
*p = 20
fmt.Printf("修改后a的值: %d\n", a)
}
运算符优先级
从高到低:
-
*/%<<>>&&^ -
+-|^ -
==!=<<=>>= -
&& -
||
示例
package main
import "fmt"
func main() {
// 优先级示例
a := 2 + 3*4
fmt.Println("2 + 3*4 =", a) // 14 (先乘后加)
b := (2 + 3) * 4
fmt.Println("(2 + 3)*4 =", b) // 20 (括号优先)
// 逻辑运算优先级
x := true || false && false
fmt.Println("true || false && false =", x) // true (&&优先于||)
y := (true || false) && false
fmt.Println("(true || false) && false =", y) // false
}
类型断言运算符
用于接口类型转换(后续章节详细介绍)。
value, ok := x.(T)
实际应用示例
示例1: 计算器
package main
import "fmt"
func calculator(a, b float64, op string) float64 {
switch op {
case "+":
return a + b
case "-":
return a - b
case "*":
return a * b
case "/":
if b != 0 {
return a / b
}
return 0
default:
return 0
}
}
func main() {
fmt.Println("10 + 5 =", calculator(10, 5, "+"))
fmt.Println("10 - 5 =", calculator(10, 5, "-"))
fmt.Println("10 * 5 =", calculator(10, 5, "*"))
fmt.Println("10 / 5 =", calculator(10, 5, "/"))
}
示例2: 判断闰年
package main
import "fmt"
func isLeapYear(year int) bool {
return (year%4 == 0 && year%100 != 0) || year%400 == 0
}
func main() {
years := []int{2000, 2020, 2021, 2024, 2100}
for _, year := range years {
if isLeapYear(year) {
fmt.Printf("%d年是闰年\n", year)
} else {
fmt.Printf("%d年不是闰年\n", year)
}
}
}
示例3: 位运算应用
package main
import "fmt"
func main() {
// 判断奇偶
num := 15
if num&1 == 0 {
fmt.Println(num, "是偶数")
} else {
fmt.Println(num, "是奇数")
}
// 交换两个数(不用临时变量)
a, b := 10, 20
fmt.Printf("交换前: a=%d, b=%d\n", a, b)
a = a ^ b
b = a ^ b
a = a ^ b
fmt.Printf("交换后: a=%d, b=%d\n", a, b)
}
练习
练习1: BMI计算器
编写程序计算BMI(身体质量指数): BMI = 体重(kg) / 身高²(m)
练习2: 温度转换
实现摄氏度、华氏度、开尔文温度之间的相互转换。
练习3: 位运算练习
使用位运算实现权限系统,支持读、写、执行三种权限的设置和检查。
练习4: 逻辑表达式
判断一个年份是否是世纪年(能被100整除)且是闰年。
小结
本节我们学习了:
-
算术运算符: +, -, *, /, %, ++, –
-
关系运算符: ==, !=, >, <, >=, <=
-
逻辑运算符: &&, ||, !
-
位运算符: &, |, ^, &^, <<, >>
-
赋值运算符: =, +=, -=等
-
运算符优先级
-
运算符的实际应用
掌握运算符是编写程序逻辑的基础。下一节,我们将学习控制流程。