当前位置: 首页 > news >正文

Golang 运算符

文章目录

  • 0.概览
  • 1.算数运算符
  • 2.关系运算符
  • 3.逻辑运算符
  • 4.位运算符
  • 5.赋值运算符
  • 6.其他运算符
  • 7.运算符优先级
  • 8.小结
  • 参考文献

0.概览

Go 语言内置运算符有:

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

1.算数运算符

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

示例:

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

2.关系运算符

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

注意:

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

示例:

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)
||逻辑或同 &&
!逻辑非同 &&(单目运算符)

示例:

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的位置清零。

  • ^

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

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

示例:

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同 <<=

示例:

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类型 + 初始化值

示例:

// &
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 的运算符设计体现了简洁性、实用性与安全性,主要有如下特点:

  • 类型安全:严格限制运算数类型,混合类型需显式转换。
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

http://www.xdnf.cn/news/1080379.html

相关文章:

  • 3D建模公司的能力与技术
  • 【Spring Boot】Druid 连接池 YAML 配置详解
  • 三、docker软件安装:gitlab,nexus,mysql8,redis,nacos,nginx
  • Apache RocketMQ进阶之路阅读笔记和疑问
  • 高职院校“赛岗课”一体化网络安全实战类人才培养方案
  • python -二叉树路径和为指定的值(根节点到叶子节点)
  • 译码器Multisim电路仿真汇总——硬件工程师笔记
  • 【机器学习深度学习】什么是下游任务模型?
  • 【STM32实践篇】:I2C驱动编写
  • 【模糊集合】示例
  • 【机器学习深度学习】AI 项目开发流程:从需求到部署的五大阶段
  • 机器学习安装使用教程
  • Python训练营打卡Day59(2025.7.3)
  • java教程——初识guava(2)
  • 这才叫窗口查询!TDEngine官方文档没讲透的实战玩法
  • 认识kubernetes kubeadm安装k8s
  • Web基础关键_007_JavaScript 的 DOM
  • 34. 在排序数组中查找元素的第一个和最后一个位置
  • WPF学习笔记(22)项面板模板ltemsPanelTemplate与三种模板总结
  • 【进阶篇-消息队列】——Kafka如何实现事务的
  • R 语言安装使用教程
  • 物联网MQTT协议与实践:从零到精通的硬核指南
  • 【2.4 漫画SpringBoot实战】
  • Java的SpringAI+Deepseek大模型实战之会话记忆
  • Qt Creator自定义控件开发流程
  • Windows 10 2016 长期服务版
  • WPF学习笔记(16)树控件TreeView与数据模板
  • 刷卡登入数据获取
  • MySQL的窗口函数介绍
  • Redis—哨兵模式