首页 / Go 语言入门教程 / 运算符全解

Go 语言入门教程

运算符全解

本教程共 80 篇 · 第 16 篇 · 更新于 2026-07-27 · 约 8 分钟阅读

GoGo 入门教程运算符算术运算符位运算优先级Go 运算符

16. 运算符全解

本节目标:掌握 Go 的所有运算符,知道运算符优先级,理解 Go 自增自减的特殊规则。

算术运算符

运算符含义示例
+3 + 2 = 5
-3 - 2 = 1
*3 * 2 = 6
/7 / 2 = 3(整数除法截断)
%取余7 % 3 = 1
++自增i++
--自减i--

整数除法

Go 的整数除法会直接截断小数部分:

fmt.Println(7 / 2)   // 3,不是 3.5
fmt.Println(-7 / 2)  // -3,向零截断

要得到浮点结果,至少有一个操作数是浮点数:

fmt.Println(7.0 / 2)  // 3.5
fmt.Println(float64(7) / 2)  // 3.5

取余

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

fmt.Println(7 % 3)   // 1
fmt.Println(-7 % 3)  // -1
fmt.Println(7 % -3)  // 1

自增自减的特殊规则

Go 的 ++--语句,不是表达式。这意味着:

  1. 只能放在变量后面:
i++    // 正确
++i    // 报错
i--    // 正确
--i    // 报错
  1. 没有返回值,不能用在表达式里:
a := i++  // 报错:i++ 不能赋值
b := i--  // 报错
  1. 只能单独作为一条语句:
i := 0
i++
fmt.Println(i)  // 1
Note

Go 把 ++-- 设计成语句而不是表达式,是为了避免 a = b++ 这种容易出错的写法。简单但安全。

关系运算符

运算符含义示例
==等于3 == 3 = true
!=不等于3 != 4 = true
<小于3 < 4 = true
<=小于等于3 <= 3 = true
>大于3 > 4 = false
>=大于等于3 >= 4 = false

比较结果都是 bool 类型。不同类型之间不能直接比较(需要类型转换)。

fmt.Println(3 == 3)        // true
fmt.Println("a" == "a")    // true
fmt.Println(3 < 4)         // true

逻辑运算符

运算符含义示例
&&逻辑与true && false = false
||逻辑或true || false = true
!逻辑非!true = false

短路求值

&&|| 有短路特性:

  • &&:如果左边是 false,右边不执行
  • ||:如果左边是 true,右边不执行
func check() bool {
    fmt.Println("check 被调用了")
    return true
}

func main() {
    false && check()   // check 不会被调用
    true || check()    // check 不会被调用
}

这个特性可以用来避免空指针等错误:

if p != nil && p.Value > 0 {
    // p 为 nil 时不会访问 p.Value,避免 panic
}

位运算符

运算符含义示例
&按位与5 & 3 = 1
|按位或5 | 3 = 7
^按位异或5 ^ 3 = 6
&^位清除(AND NOT)5 &^ 3 = 4
<<左移1 << 3 = 8
>>右移8 >> 2 = 2

按位与 &

对应位都为 1,结果才为 1:

fmt.Println(5 & 3)  // 1
// 5 = 101
// 3 = 011
// & = 001 = 1

按位或 |

对应位有一个为 1,结果就为 1:

fmt.Println(5 | 3)  // 7
// 5 = 101
// 3 = 011
// | = 111 = 7

按位异或 ^

对应位不同为 1,相同为 0:

fmt.Println(5 ^ 3)  // 6
// 5 = 101
// 3 = 011
// ^ = 110 = 6

取反 ^

^ 用在单个操作数上时,是按位取反:

fmt.Println(^5)  // -6
Tip

Go 没有 ~ 运算符,取反用的是 ^。同一个符号在不同上下文有不同含义:两个操作数时是异或,一个操作数时是取反。

位清除 &^

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

fmt.Println(5 &^ 3)  // 4
// 5 = 101
// 3 = 011
// 清除第0、1位
// 结果 = 100 = 4

左移 << 和 右移 >>

fmt.Println(1 << 3)   // 8,二进制 1000
fmt.Println(8 >> 2)   // 2,二进制 10

左移相当于乘 2 的 n 次方,右移相当于除以 2 的 n 次方(向下取整)。

位运算实战:权限标志

const (
    Read    = 1 << iota  // 1 (001)
    Write                // 2 (010)
    Execute              // 4 (100)
)

// 组合权限
perm := Read | Write  // 3 (011)

// 检查权限
hasRead := perm & Read != 0      // true
hasExec := perm & Execute != 0   // false

// 移除权限
perm = perm &^ Write  // 1 (001),移除了写权限

赋值运算符

运算符等价写法
=a = b
+=a = a + b
-=a = a - b
*=a = a * b
/=a = a / b
%=a = a % b
&=a = a & b
|=a = a | b
^=a = a ^ b
<<=a = a << b
>>=a = a >> b
&^=a = a &^ b
a := 10
a += 5   // a = 15
a -= 3   // a = 12
a *= 2   // a = 24
a /= 5   // a = 4
a <<= 3  // a = 32

其他运算符

运算符含义示例
&取地址&x
*解引用*p
<-接收(channel)<-ch

取地址和解引用在指针章节详细讲,channel 操作在并发章节讲。

运算符优先级

Go 的运算符优先级从高到低:

优先级运算符
5* / % << >> & &^
4+ - | ^
3== != < <= > >=
2&&
1||

优先级高的先计算。优先级相同时,从左到右计算。

// 乘除优先于加减
fmt.Println(2 + 3 * 4)  // 14,不是 20

// 比较优先于逻辑
fmt.Println(1 < 2 && 3 > 2)  // true

// 位运算优先级
fmt.Println(1 + 2 << 1)  // 5,先算 2<<1=4,再 1+4=5
Tip

优先级记不住没关系,用括号。2 + (3 * 4) 比靠优先级判断更清晰,也不会出错。

Go 没有的运算符

和其他语言比,Go 少了一些运算符:

运算符说明
?:(三元)Go 没有,用 if-else 替代
++i(前置自增)Go 只有后置 i++
--i(前置自减)Go 只有后置 i--
~(取反)Go 用 ^ 代替

没有三元运算符

// 其他语言
// result := condition ? a : b

// Go 的写法
var result int
if condition {
    result = a
} else {
    result = b
}

虽然啰嗦一些,但更清晰。Go 的设计哲学就是不追求代码极致简短,而追求可读性。

字符串拼接运算符

+ 可以拼接字符串:

s := "Hello" + ", " + "World"

+= 可以追加:

s := "Hello"
s += " World"
Warning

字符串拼接会产生新字符串。循环里大量拼接用 strings.Builder,不要用 +

学完这节你能做什么

  • 使用所有算术、关系、逻辑、位运算符
  • 知道运算符优先级,合理使用括号
  • 理解 Go 自增自减的特殊规则
  • 用位运算做权限标志
  • 知道 Go 有哪些运算符没有,以及替代方案

下一节进入流程控制,从 if-else 开始。