运算符
运算符是告诉编译器执行特定数学或逻辑操作的符号。
算术运算符
用来对数字进行数学运算,比如加减乘除。
go
func main() {
a := 10
b := 2
fmt.Println("a + b =", a+b) // 12
fmt.Println("a - b =", a-b) // 8
fmt.Println("a * b =", a*b) // 20
fmt.Println("a / b =", a/b) // 5
fmt.Println("a % b =", a%b) // 0 求余
// 余数 = 被除数 - (被除数/除数) * 除数
fmt.Println("10%3\t=", 10%3) // 1
fmt.Println("-10/3\t=", -10%3) // -1
fmt.Println("10/-3\t=", 10%-3) // 1
fmt.Println("-10/-3\t=", -10%-3) // -1
a++ // 自增和自减都是语句,而不是运算符
fmt.Println("a++ =", a) // 11 自增
a--
fmt.Println("a-- =", a) // 10 自减
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
整型溢出
go
func main() {
var a int8 = 127
println(a) // 127
a++
println(a) // -128 整型溢出
var b uint8 = 255
println(b) // 255
b++
println(b) // 0
// var c int8 = 128 // 超出 int8 范围,编译出错 overflows 溢出
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
当需要处理的数太大(超过 1018),内置类型就不够用了,这时可以使用 big 包。
比较运算符
用于对常量、变量或表达式的结果进行比较。如果比较是成立的,则返回 true,反之则返回 false。
go
func main() {
a := 10
b := 2
fmt.Println("a 等于 b\t", a == b) // false
fmt.Println("a 不等于 b\t", a != b) // true
fmt.Println("a 大于 b\t", a > b) // true
fmt.Println("a 大于等于 b\t", a >= b) // true
fmt.Println("a 小于 b\t", a < b) // false
fmt.Println("a 小于等于 b\t", a <= b) // false
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
浮点型比较
浮点型比较时,需要注意精度问题。
go
func main() {
money := 0.1
money += 0.2
fmt.Println(money == 0.3) // false
fmt.Println((money - 0.3) < 0.0001) // true 临时解决方案
}
1
2
3
4
5
6
2
3
4
5
6
逻辑运算符
逻辑运算符有三种:与(&&)、或(||)、非(!),只针对于布尔型数据或表达式使用。
a | b | a and b | a or b | not a |
---|---|---|---|---|
true | true | true | true | false |
true | false | false | true | false |
false | true | false | true | true |
false | false | false | false | true |
go
func main() {
a := true
b := false
fmt.Println(a && b) // false
fmt.Println(a || b) // true
fmt.Println(!a) // false
}
1
2
3
4
5
6
7
2
3
4
5
6
7
按位运算符
是对内存中二进制位进行操作。
运算符 | 描述 |
---|---|
& | 按位与,对应二进位相与(均为 1 才为 1) |
l | 按位或,对应二进位相或(有一个为 1 就为 1) |
^ | 按位异或,对应二进位异或(两位不一样则为 1) |
<< | 左移 n 位就是乘以 2 的 n 次方,高位丢弃,低位补 0 |
>> | 正数右移,高位补 0;负数右移,高位补 1。右移 n 位就是除以 2 的 n 次方 |
&^ | 与非,按位清零,第二位为 1,则结果对应位清零;为 0,则结果对应位采用第一位值 |
go
func main() {
a := 1 // 001
b := 5 // 101
fmt.Println(a & b) // 001 结果 1
fmt.Println(a | b) // 101 结果 5
fmt.Println(a ^ b) // 100 结果 4
fmt.Println(a << 2) // 100 结果 4
fmt.Println(b >> 2) // 001 结果 1
fmt.Println(a &^ b) // 000 结果 0
fmt.Println(b &^ a) // 100 结果 4
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
赋值运算符
Go 中最常见、最基本的赋值运算符是等号=,用来将一个表达式的值赋给一个变量。
运算符 | 描述 |
---|---|
= | 将一个表达式的值赋给一个变量 |
+= | 相加后再赋值 |
-= | 相减后再赋值 |
*= | 相乘后再赋值 |
/= | 相除后再赋值 |
%= | 求余后再赋值 |
«= | 左移后赋值 |
»= | 右移后赋值 |
&= | 按位与后赋值 |
|= | 按位或后赋值 |
^= | 按位异或后赋值 |
go
func main() {
a := 1
a += 1
fmt.Println(a) // 2
}
1
2
3
4
5
2
3
4
5
地址运算符
符号 | 名称 | 作用 |
---|---|---|
&变量 | 取址符 | 返回变量在内存中的地址 |
*指针变量 | 取值符 | 返回指针指向变量的值,解引用、间接引用 |
& 操作符无法获得字面值的地址,如 &100,会导致编译器报错。
go
func main() {
a := 100
p := &a
fmt.Println("p值:", p) // p值: 0xc00000a0c8 a的地址
fmt.Println("p地址对应值:", *p) // p地址对应值: 100 a的值
}
1
2
3
4
5
6
2
3
4
5
6
运算符优先级
所谓优先级,就是当多个运算符同时出现在一个表达式中时,先执行哪个运算符的问题。
go
func main() {
fmt.Println(2 + 3*3) // 11
fmt.Println((2 + 3) * 3) // 15
}
1
2
3
4
2
3
4
可以看到,Go 会先计算乘法再计算加法,这也符合我们小学学过的四则运算法则,先乘除后加减。在实际开发中,如果搞不清楚运算符优先级,可以使用小括号来确保运算的执行顺序。
详细的运算符优先级,可参考官方文档:https://golang.google.cn/ref/spec#Operators