复制成功
请遵守本站 许可
REPORT
Chapter_Post // Field_Report

Post_Ref: RL-CH08-OPE

2026.05.15

Ch.08:Go的运算符

Chongxi
Chongxi
Listening: IDLE_SESSION
#教程#Golang
ANALYSIS

TL;DR:本文介绍了在Golang中的算术运算符

运算符是程序里最基础的计算工具。本篇会把 Go 的所有运算符过一遍,重点放在和其他语言不同的地方

算术运算符#

最基本的数学运算:

运算符含义示例
+1 + 2 = 3
-5 - 3 = 2
*3 * 4 = 12
/10 / 3 = 3
%取余10 % 3 = 1

简单吧,但是除法要注意下

整数除法直接截断:

PRTCL // GO
fmt.Println(10 / 3) // 3,不是 3.333...
fmt.Println(10.0 / 3) // 3.3333333333333335

两个整数相除,结果还是整数,小数部分直接丢掉。要得到小数结果,必须有一方是浮点数:

PRTCL // GO
a := 10
b := 3
fmt.Println(float64(a) / float64(b)) // 3.3333333333333335

取余的结果符号和被除数一致:

PRTCL // GO
fmt.Println(10 % 3) // 1
fmt.Println(-10 % 3) // -1,结果是负数
fmt.Println(10 % -3) // 1,结果是正数

取余结果的正负,跟被除数(左边那个数)一致,和除数(右边)无关

+ 用于字符串拼接:

PRTCL // GO
a := "Hello"
b := "Go"
fmt.Println(a + ", " + b + "!") // Hello, Go!

自增和自减#

Go 有 ++--,但和其他语言有个重要区别:

PRTCL // GO
a := 1
a++ // a = 2
a-- // a = 1

Go 的 ++-- 是语句,不是表达式,不能放在赋值右边:

PRTCL // GO
a := 1
b := a++ // ❌ 报错

也没有前置的 ++a

PRTCL // GO
++a // ❌ 报错

只有 a++a--,而且只能单独成行。Go 的设计去掉了 i++ + ++i 这类让人困惑的写法

赋值运算符#

基本赋值:

PRTCL // GO
a := 10
a = 20 // 重新赋值

复合赋值,把运算和赋值合在一起:

PRTCL // GO
a := 10
a += 5 // a = a + 5 = 15
a -= 3 // a = a - 3 = 12
a *= 2 // a = a * 2 = 24
a /= 4 // a = a / 4 = 6
a %= 4 // a = a % 4 = 2

字符串也可以用 +=

PRTCL // GO
s := "Hello"
s += ", Go!"
fmt.Println(s) // Hello, Go!

比较运算符#

比较运算符的结果是布尔值 truefalse

运算符含义
==等于
!=不等于
>大于
<小于
>=大于等于
<=小于等于
PRTCL // GO
fmt.Println(1 == 1) // true
fmt.Println(1 != 2) // true
fmt.Println(3 > 2) // true
fmt.Println(3 < 2) // false

只有相同类型才能比较:

PRTCL // GO
var a int = 1
var b int32 = 1
fmt.Println(a == b) // ❌ 报错,int 和 int32 不同类型

必须转换成同一类型再比较:

PRTCL // GO
fmt.Println(a == int(b)) // ✅ true

字符串比较按字典序:

PRTCL // GO
fmt.Println("abc" == "abc") // true
fmt.Println("abc" < "abd") // true,c < d
fmt.Println("abc" > "ab") // true,更长的字符串更大

浮点数比较要小心:

PRTCL // GO
a := 0.1 + 0.2
b := 0.3
fmt.Println(a == b) // false,精度问题

浮点数不能直接用 == 比较,应该判断差值是否足够小:

PRTCL // GO
import "math"
diff := math.Abs(a - b)
fmt.Println(diff < 1e-9) // true,认为相等

逻辑运算符#

用于组合多个布尔条件:

运算符含义示例
&&与,两边都为 true 才是 truetrue && false = false
||或,一边为 true 就是 truetrue || false = true
!非,取反!true = false
PRTCL // GO
age := 20
hasID := true
// 成年且有证件
if age >= 18 && hasID {
fmt.Println("pass")
}
// 是管理员或者是超级用户
isAdmin := false
isSuperUser := true
if isAdmin || isSuperUser {
fmt.Println("pass")
}
// 不是访客
isGuest := false
if !isGuest {
fmt.Println("not guess")
}

短路求值

&&|| 都有短路特性:

PRTCL // GO
// && 左边是 false,右边不会执行
false && someFunc() // someFunc() 不会被调用
// || 左边是 true,右边不会执行
true || someFunc() // someFunc() 不会被调用

利用这个特性可以避免空指针等问题:

PRTCL // GO
// 先检查 user 不为空,再访问 user.Name
if user != nil && user.Name == "admin" {
fmt.Println("是管理员")
}

如果 user 是 nil,&& 短路,不会执行右边,就不会因为访问 nil 的字段而崩溃

位运算符#

位运算直接操作二进制位,在处理权限、标志位、底层协议时很常用:

运算符含义示例
&按位与0101 & 0011 = 0001
|按位或0101 | 0011 = 0111
^按位异或0101 ^ 0011 = 0110
<<左移1 << 3 = 8
>>右移8 >> 1 = 4
&^按位清零(Go 特有)0101 &^ 0011 = 0100

左移和右移

左移一位相当于乘以 2,右移一位相当于除以 2:

PRTCL // GO
fmt.Println(1 << 3) // 8,1 × 2³
fmt.Println(8 >> 1) // 4,8 ÷ 2

上一篇 iota 里定义文件大小就是用的左移:

PRTCL // GO
const (
_ = iota
KB = 1 << (10 * iota) // 1024
MB // 1048576
GB // 1073741824
)

按位与用来检查标志位:

PRTCL // GO
const (
PermRead = 1 << iota // 001
PermWrite // 010
PermExecute // 100
)
perm := PermRead | PermWrite // 011,有读和写权限
// 检查是否有读权限
if perm & PermRead != 0 {
fmt.Println("有读权限")
}
// 检查是否有执行权限
if perm & PermExecute != 0 {
fmt.Println("有执行权限")
} else {
fmt.Println("没有执行权限")
}

&^ 按位清零,Go 特有

a &^ b 的意思是:把 b 中为 1 的位,在 a 中清零:

PRTCL // GO
perm := PermRead | PermWrite // 011
// 去掉写权限
perm = perm &^ PermWrite // 001
fmt.Println(perm & PermWrite != 0) // false,写权限没了

其他语言一般用 a & ~b 实现同样效果,Go 的这个操作单独成一个运算符

运算优先级#

当一个表达式里有多个运算符时,优先级决定计算顺序。Go 的优先级从高到低:

优先级运算符
5(最高)* / % << >> & &^
4+ - | ^
3== != < <= > >=
2&&
1(最低)||
PRTCL // GO
fmt.Println(2 + 3*4) // 14,乘法优先
fmt.Println(2 > 1 && 3 > 2) // true,比较优先于 &&

不要依赖优先级,用括号写清楚:

PRTCL // GO
// 不清晰
result := a + b * c >> 2 & mask
// 清晰
result := ((a + (b * c)) >> 2) & mask

优先级规则不用背,遇到不确定的就加括号,清晰又不易错

运算符的一些细节#

^ 在 Go 里有两个用途

作为二元运算符是按位异或:

PRTCL // GO
fmt.Println(5 ^ 3) // 6,0101 ^ 0011 = 0110

作为一元运算符是按位取反(其他语言一般用 ~):

PRTCL // GO
var a uint8 = 5 // 00000101
fmt.Println(^a) // 250,11111010

整数除法和取余的关系

PRTCL // GO
a, b := 10, 3
q := a / b // 商 3
r := a % b // 余数 1
// 验证:q*b + r == a 永远成立
fmt.Println(q*b+r == a) // true

字符串不支持 -*/ 运算:

PRTCL // GO
"hello" - "world" // ❌ 报错
"hello" * 3 // ❌ 报错,Python 里可以但 Go 不行

字符串重复用 strings.Repeat()

PRTCL // GO
fmt.Println(strings.Repeat("go", 3)) // gogogo

下一篇讲 if 语句,条件判断的完整用法,以及 Go 里 if 特有的初始化语句写法

R P
Rhine Lab Pioneer Division
Auth_Verified: 2026.05.15
// END OF POST
Donation_Channel // Support_Us

如果觉得本文不错,不妨请我喝杯咖啡。

爱发电
golearn
Series_Associated // 专题收录

从0带你学Golang

该文章已被收录至本站深度研究专题。点击进入项目主页,查看完整研究序列。

Classified
Chapter_06 // Legal_Protocol
Protocol_Ref: CC-BY-NC-SA-4.0

Ch.08:Go的运算符

Author: CHONGXI // Released: 2026.05.15

本受试报告采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 许可协议进行分发。

} } out>