Golang 运算符

文章目录

0.概览

Go 语言内置运算符有:

  • 算术运算符
  • 关系运算符
  • 逻辑运算符
  • 位运算符
  • 赋值运算符
  • 特殊运算符

1.算数运算符

运算符 说明 运算数要求
+ 加法 数值类型(整型、浮点型、复数)或字符串(仅拼接)
- 减法 数值类型(整型、浮点型、复数)
* 乘法 数值类型(整型、浮点型、复数)
/ 除法 数值类型(整型、浮点型、复数),除数不能为0
% 取模(取余) 仅限整型,除数不能为0
++ 自增 数值类型变量(不能用于常量),不返回值(不能参与表达式)
-- 自减 数值类型变量(不能用于常量),不返回值(不能参与表达式)

示例:

go 复制代码
a := 10 % 3   // 合法(整型)
b := 5.0 / 2  // 合法(浮点型)
c := "Go" + "lang" // 合法(字符串拼接)
d := 10 / 0   // 非法(除数为0)
e := 5.2 % 3  // 非法(浮点型不能取模)

2.关系运算符

运算符 名称 运算数要求
== 等于 可比较类型(数值、字符串、布尔、指针、通道、接口、结构体/数组*)
!= 不等于 同 ==
> 大于 数值类型或字符串(按字典序)
< 小于 同 >
>= 大于等于 同 >
<= 小于等于 同 >

注意:

  • 结构体和数组要求所有字段/元素可比较。
  • 切片、map、函数不可比较(只能与 nil 比较)。

示例:

go 复制代码
fmt.Println(3 > 2)         // true(数值)
fmt.Println("abc" < "def") // true(字符串字典序)
var s []int
fmt.Println(s == nil)      // true(切片可与nil比较)
fmt.Println([]int{1} == []int{1}) // 非法(切片不能直接比较)

3.逻辑运算符

运算符 名称 运算数要求
&& 逻辑与 布尔类型(true/false)
` `
! 逻辑非 同 &&(单目运算符)

示例:

go 复制代码
fmt.Println(true && false) // false
fmt.Println(!(5 > 3))     // false(需先通过比较得到布尔值)
fmt.Println(1 && 0)       // 非法(非布尔类型)

4.位运算符

运算符 名称 运算数要求
& 按位与 仅限整型
` ` 按位或
^ 按位异或 同 &(或单目取反)
&^ 按位清除 同 &
<< 左移位 左操作数整型,右操作数无符号整型
>> 右移位 同 <<

移位规则:

  • 左移:低位补0
  • 右移:
    • 无符号整型:高位补0
    • 有符号整型:高位补符号位(算术右移)

特殊的位运算符:

  • &^

m &^ n等价于m & (^n)

&^ 是 Golang 中特有的一个位运算符,作用是按位清除 (Bit Clear),将左操作数中,对应右操作数位为1的位置清零。

  • ^

^ 既是是双目运算符,也是单目运算符。

双目运算符为异或运算,单目运算符为按位取反。其他编程语言按位取反的运算符一般为 ~

示例:

go 复制代码
a := 6 &^ 3  // 按位清除:0110 &^ 0011 = 0100 (4)
b := 1 << 3  // 8(左移3位)
c := -8 >> 2 // -2(算术右移)
d := 3.5 << 2 // 非法(浮点型不能移位)

fmt.Printf("%b", ^uint8(2)) // 按位取反,输出 11111101

5.赋值运算符

运算符 说明 等价形式 运算数要求
= 基本赋值 - 左值必须为变量(类型匹配)
+= 加后赋值 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 同 <<=

示例:

go 复制代码
var x int
x += 5      // 合法(算术运算)
y := 10
y &= 3     // 合法(位运算)
var f float64
f %= 2      // 非法(浮点型不能取模)

6.特殊运算符

在 Go 语言中,除了之前提到的五类主要运算符,还有一些重要的特殊运算符,它们提供了底层内存操作、类型处理、通道控制等核心功能。

运算符 名称 说明 运算数要求
& 取地址 返回变量的内存地址 必须是可寻址的值(变量、切片元素、结构体字段等),常量、字面量、函数返回值不可用。
* 解引用 访问指针指向的值 必须是指针类型
<- 通道操作 1. 发送值到通道。 2. 从通道接收值 1. 左侧必须是通道,右侧值类型需匹配通道类型。 2. 必须是通道类型。
: 切片/数组 创建切片或截取子数组 数组/切片 + 索引(可选)
.(T) 类型断言 1. 检查接口值的实际类型 2. 将接口值转换为具体类型 必须是接口类型
... 可变参数 1. 函数参数:表示可变参数 2. 切片展开:将切片元素作为独立参数传入 1. 函数参数列表 2. 切片类型
, 逗号操作符 1. 多变量声明/赋值 2. 多返回值处理 3. 忽略返回值 无特殊限制
: 标签 标记代码位置(用于 break/continue/goto) 必须与 break/continue/goto 配合使用
{} 复合字面量 初始化结构体、数组、切片、map 类型 + 初始化值

示例:

go 复制代码
// &
x := 10
p := &x 			// p 是指向 x 的指针
py := &10           // 错误:字面量不可寻址
pf := &fmt.Println  // 错误:函数不可寻址

// *
fmt.Println(*p) // 输出 10

// <-
ch <- data // 发送
data := <-ch // 接收

// :
s := arr[1:4] // 截取索引1-3

// .(T)
str := val.(string) // 断言为string

// ...
func sum(nums ...int){}
sum(slice...)

// ,
a, b := 1, 2
_, err := func()
for i, v := range slice

// :
loop: for {... break loop}

// {}
p := Point{X: 1, Y: 2}
m := map[string]int{"a": 1}

7.运算符优先级

运算符优先级确定表达式中的分组。这会影响表达式的计算方式。

在 Go 语言中,一元运算符(一些只需要一个操作数的运算符称为一元运算符(或单目运算符)。)拥有最高的优先级,二元运算符的运算方向均是从左至右。

当表达式包含多种运算符时,按以下优先级执行(从高到低):

优先级 运算符 说明 结合性
1 () [] {} . 函数调用 数组索引 复合字面量 选择器(结构体字段) 从左到右
2 ++ -- + - ! ^ * & <- 自增/自减 正号/负号 逻辑非 按位取反 解引用 取地址 接收操作符 从右到左
3 * / % << >> & &^ 乘法/除法/取模 位左移/右移 按位与 按位清除 从左到右
4 + - ` ^` 加法/减法 按位或 按位异或
5 == != < <= > >= 关系运算符 从左到右
6 && 逻辑与 从左到右
7 ` `
8 <- 发送操作符 从右到左
9 = += -= *= /= %= <<= >>= &= ^= &^= 赋值运算符 从右到左

记忆口诀:单目 > 算术 > 移位 > 关系 > 逻辑 > 赋值。

记住:当有疑问时,使用括号明确运算顺序,这既能保证正确性,也能提高代码可读性。

8.小结

Golang 的运算符设计体现了简洁性、实用性与安全性,主要有如下特点:

  • 类型安全:严格限制运算数类型,混合类型需显式转换。
go 复制代码
a := int32(5) + int64(10) // 非法!需统一类型
  • 零值安全:变量声明自动初始化零值,但除数为 0 会 panic。
  • 不可比较类型:切片、map、函数只能与 nil 比较。
  • 移位限制:移位右操作数必须为无符号整型。
  • 自增/自减:只能独立使用(i++ 合法,j = i++ 非法)。
  • 指针访问:统一使用 .(自动解引用),没有 -> 运算符。
  • 接口类型断言:必须使用 .(T) 语法,建议用安全形式:val, ok := interfaceVar.(Type)
  • 通道操作:<- 既用于发送也用于接收,根据位置区分。
  • 字符串拼接:+ 支持字符串拼接,效率低时用 strings.Builder
  • 运算符优先级:明确分级,括号优先。

Go 的运算符设计体现了 "显式优于隐式" 的哲学,通过掌握这些运算符的特性和最佳实践,可以编写出更高效、更安全的 Go 代码。


参考文献

The Go Programming Language Specification

相关推荐
iso少年1 天前
Go 语言并发编程核心与用法
开发语言·后端·golang
风送雨1 天前
Go 语言进阶学习:第 2 周 —— 接口、反射与错误处理进阶
开发语言·学习·golang
峰上踏雪1 天前
Go(Golang)Windows 环境配置关键点总结
开发语言·windows·golang·go语言
我不是8神1 天前
go语言语法基础全面总结
开发语言·golang·xcode
qq_172805591 天前
Modbus Server 模拟平台之RTU协议
golang·modbus
源代码•宸1 天前
Leetcode—1339. 分裂二叉树的最大乘积【中等】
开发语言·后端·算法·leetcode·golang·dfs
源代码•宸1 天前
Leetcode—166. 加一【简单】new(big.Int)法
经验分享·算法·leetcode·职场和发展·golang·new.bigint
源代码•宸1 天前
GoLang基础语法(go语言结构、go语言变量、go语言常量、go语言运算符)
开发语言·后端·golang
ghostwritten1 天前
go.mod 与go.sum有什么区别?
开发语言·后端·golang
海奥华21 天前
Golang Channel 原理深度解析
服务器·开发语言·网络·数据结构·算法·golang