Go 语言变量、常量、运算符)
- [一、Go 变量](#一、Go 变量)
-
- [1.1 变量命名规则](#1.1 变量命名规则)
- [1.2 变量声明四大方式](#1.2 变量声明四大方式)
- [1.3 多变量声明](#1.3 多变量声明)
- [1.4 变量作用域](#1.4 变量作用域)
- [1.5 空白标识符 `_`](#1.5 空白标识符
_) - [1.6 值类型 & 引用类型](#1.6 值类型 & 引用类型)
-
- [1. 值类型](#1. 值类型)
- 示例
- [2. 引用类型](#2. 引用类型)
- [二、Go 常量](#二、Go 常量)
- [三、Go 运算符](#三、Go 运算符)
一、Go 变量
变量用于存储数据,可读写、运行过程中值可修改。Go 是静态强类型语言,变量必须先声明再使用。
1.1 变量命名规则
说明
- 由字母、数字、下划线
_组成; - 首字符不能是数字;
- 不能使用 Go 关键字作为变量名;
- 区分大小写;
- 见名知意,推荐驼峰命名。
合法/非法示例
- 合法:
name、_age、userID、num123 - 非法:
123abc(数字开头)、a+b(含特殊符号)、case(关键字)
1.2 变量声明四大方式
方式1:标准声明(var + 变量名 + 类型)
语法
go
var 变量名 数据类型
说明
只声明、不初始化,变量会自动赋予零值。
零值规则(重点)
- 数值类型(int/float):
0 - 布尔类型:
false - 字符串:
""(空字符串) - 指针、切片、map、channel、函数、error:
nil
示例
go
package main
import "fmt"
func main() {
var a int
var b float64
var c bool
var d string
fmt.Printf("a=%d, b=%f, c=%t, d=%q\n", a, b, c, d)
}
运行结果
a=0, b=0.000000, c=false, d=""
踩坑
只声明不赋值的局部变量必须使用 ,否则编译报错 declared but not used;全局变量允许声明不使用。
方式2:声明并初始化(var + 变量名 + 类型 + 值)
语法
go
var 变量名 类型 = 值
示例
go
package main
import "fmt"
func main() {
var name string = "张三"
var age int = 20
fmt.Println(name, age)
}
方式3:类型推断(省略类型,编译器自动识别)
语法
go
var 变量名 = 值
说明
根据右侧值自动推导变量类型,日常使用频率很高。
示例
go
package main
import "fmt"
func main() {
var str = "Go语言"
var num = 100
fmt.Println(str, num)
}
方式4:短变量声明(:=,最常用)
语法
go
变量名 := 值
说明
- 等价于
var 变量名 类型 = 值; - 只能在函数内部使用,不能声明全局变量;
- 必须同时声明+赋值,不能只声明不赋值。
示例
go
package main
import "fmt"
func main() {
msg := "短变量声明"
fmt.Println(msg)
}
踩坑(高频错误)
-
同一作用域不能重复用
:=声明同名变量gofunc main() { a := 10 a := 20 // 报错:no new variables on left side of := }修正:直接赋值
a = 20。 -
:=不能用于全局变量gomsg := "全局变量" // 语法报错修正:全局变量使用
var声明。
1.3 多变量声明
1. 同行声明多个同类型变量
go
var v1, v2, v3 类型
var v1, v2, v3 类型 = 值1, 值2, 值3
示例:
go
var a, b int = 1, 2
fmt.Println(a, b)
2. 同行声明多个不同类型变量(类型推断)
go
var v1, v2 = 值1, 值2
示例:
go
var name, age = "李四", 22
fmt.Println(name, age)
3. 因式分解写法(推荐全局变量)
批量声明多个不同类型全局变量,代码整洁。
语法
go
var (
变量1 类型 = 值1
变量2 类型 = 值2
变量3 = 值3
)
示例
go
package main
import "fmt"
// 全局变量组
var (
id int = 1
addr string = "北京"
flag = true
)
func main() {
fmt.Println(id, addr, flag)
}
4. 短变量多变量声明(函数内)
go
v1, v2 := 值1, 值2
示例:
go
func main() {
x, y := 10, "test"
fmt.Println(x, y)
}
1.4 变量作用域
- 局部变量:函数/代码块内声明,仅当前代码块有效,函数执行完毕自动销毁。
- 全局变量 :函数外声明,整个包内有效;首字母大写可跨包访问。
- 变量重名 :局部变量和全局变量可以同名,局部变量优先(就近原则)。
示例
go
package main
import "fmt"
// 全局变量
var num int = 100
func main() {
// 局部变量,覆盖全局
var num int = 200
fmt.Println(num) // 输出 200
}
1.5 空白标识符 _
说明
_ 是只写变量 ,用于丢弃不需要的返回值,解决 Go 变量必须被使用的规则。
语法
go
_, 变量 = 返回值1, 返回值2
示例
go
package main
import "fmt"
// 函数返回两个值
func calc() (int, int) {
return 10, 20
}
func main() {
// 丢弃第一个返回值,只接收第二个
_, b := calc()
fmt.Println(b) // 20
}
踩坑
不能读取 _ 的值,fmt.Println(_) 直接编译报错。
1.6 值类型 & 引用类型
1. 值类型
- 包含:
int、float、bool、string、数组 - 特点:赋值时完整拷贝数据,新旧变量互不影响;变量存储在栈内存。
示例
go
a := 10
b := a
b = 20
fmt.Println(a) // 10,a 不受影响
2. 引用类型
- 包含:
切片、map、指针、channel、函数 - 特点:赋值时只拷贝内存地址,多个变量指向同一份数据;修改一个,全部受影响。
二、Go 常量
常量是程序运行期间值固定不可修改 的量,使用 const 声明。
2.1 常量基础语法
说明
- 常量只能修饰:布尔、数值、字符串类型;
- 声明时必须赋值,无零值概念;
- 不能使用
:=声明常量。
基础语法
go
// 显式指定类型
const 常量名 类型 = 值
// 类型推断(省略类型,推荐)
const 常量名 = 值
示例
go
package main
import "fmt"
func main() {
const PI float64 = 3.14159
const NAME = "Go学习"
fmt.Println(PI, NAME)
}
踩坑
常量声明后禁止修改,如下代码直接编译报错:
go
const a = 10
a = 20 // 报错:cannot assign to a
2.2 多常量声明
1. 同行多常量
go
const c1, c2 = 值1, 值2
2. 因式分解批量常量(常用,枚举场景)
go
const (
常量1 = 值1
常量2 = 值2
常量3 = 值3
)
示例(简单枚举):
go
const (
UNKNOWN = 0
MALE = 1
FEMALE = 2
)
2.3 常量与内置函数
常量表达式中可以使用 Go 内置函数 (len、cap、unsafe.Sizeof),普通自定义函数不支持。
示例
go
package main
import (
"fmt"
"unsafe"
)
const (
str = "hello"
l = len(str)
s = unsafe.Sizeof(str)
)
func main() {
fmt.Println(str, l, s)
}
2.4 特殊常量:iota(枚举计数器)
核心规则
iota是常量组专用计数器;const关键字出现时,iota重置为0;- 常量组内每新增一行 ,
iota自动 +1; - 上一行常量无赋值时,默认继承上一行表达式。
用法1:基础自增
go
package main
import "fmt"
const (
a = iota // 0
b // 1(继承 a = iota)
c // 2
)
func main() {
fmt.Println(a, b, c) // 0 1 2
}
用法2:穿插自定义值,打断自增
go
const (
a = iota // 0
b // 1
d = "ha" // 自定义值,iota+1 → 2
e // "ha",iota+1 → 3
f = 100 // 自定义值,iota+1 → 4
g // 100,iota+1 → 5
h = iota // 5
)
用法3:位运算结合 iota(经典场景)
go
package main
import "fmt"
const (
i = 1 << iota // 1 << 0 = 1
j = 3 << iota // 3 << 1 = 6
k // 3 << 2 = 12
l // 3 << 3 = 24
)
func main() {
fmt.Println(i, j, k, l) // 1 6 12 24
}
踩坑
iota仅在const常量组内生效,单独使用无效;- 普通变量不能使用
iota。
三、Go 运算符
运算符用于数据运算、逻辑判断,分为:算术、关系、逻辑、位、赋值、其他运算符,同时包含优先级规则。
3.1 算术运算符
适用于数值类型,共 7 个。
| 运算符 | 作用 | 示例(A=10,B=20) |
|---|---|---|
+ |
相加 | A+B = 30 |
- |
相减 | A-B = -10 |
* |
相乘 | A*B = 200 |
/ |
整除 | B/A = 2 |
% |
取余 | B%A = 0 |
++ |
自增 | A++ → 11 |
-- |
自减 | A-- → 9 |
完整示例
go
package main
import "fmt"
func main() {
var a = 21
var b = 10
fmt.Println(a + b)
fmt.Println(a - b)
fmt.Println(a * b)
fmt.Println(a / b)
fmt.Println(a % b)
a++
fmt.Println(a)
a--
fmt.Println(a)
}
高频踩坑
-
整数相除结果为整数 ,小数部分直接舍弃:
5 / 2 = 2; -
自增/自减只能单独使用 ,不能参与赋值运算:
goa := 10 b := a++ // 编译报错,Go 不支持 -
取余
%不能用于浮点类型。
3.2 关系运算符(比较运算符)
返回结果为 bool 类型(true/false),常用于 if/for 判断。
| 运算符 | 作用 |
|---|---|
== |
相等 |
!= |
不相等 |
> |
大于 |
< |
小于 |
>= |
大于等于 |
<= |
小于等于 |
示例
go
package main
import "fmt"
func main() {
a := 21
b := 10
if a == b {
fmt.Println("相等")
} else {
fmt.Println("不相等")
}
fmt.Println(a > b)
}
踩坑
判断相等是 ==,不要写成赋值 =。
3.3 逻辑运算符
多用于多条件组合判断,操作数和结果均为布尔值。
| 运算符 | 名称 | 规则 |
|---|---|---|
&& |
逻辑与 | 两边都为 true,结果才为 true(短路:左边 false 直接终止) |
| ` | ` | |
! |
逻辑非 | 取反,true → false,false → true |
示例
go
package main
import "fmt"
func main() {
a := true
b := false
fmt.Println(a && b) // false
fmt.Println(a || b) // true
fmt.Println(!a) // false
}
3.4 位运算符
对整数二进制位 进行操作,底层开发、权限掩码常用。
假定:a=60(0011 1100),b=13(0000 1101)
| 运算符 | 作用 | 结果 |
|---|---|---|
& |
按位与 | 对应位都为1才为1 → 12 |
| ` | ` | 按位或 |
^ |
按位异或 | 对应位不同则为1 → 49 |
<< |
左移 n 位 | 整体左移,低位补0 → a<<2 = 240 |
>> |
右移 n 位 | 整体右移,高位补0 → a>>2 = 15 |
示例
go
package main
import "fmt"
func main() {
var a uint = 60
var b uint = 13
fmt.Println(a & b)
fmt.Println(a | b)
fmt.Println(a ^ b)
fmt.Println(a << 2)
fmt.Println(a >> 2)
}
3.5 赋值运算符
结合运算 + 赋值,简化代码写法。
| 运算符 | 等价写法 |
|---|---|
= |
基础赋值 |
+= |
a = a + b |
-= |
a = a - b |
*= |
a = a * b |
/= |
a = a / b |
%= |
a = a % b |
<<= |
左移后赋值 |
>>= |
右移后赋值 |
&= |
按位与后赋值 |
| ` | =` |
^= |
按位异或后赋值 |
示例
go
package main
import "fmt"
func main() {
a := 10
a += 5 // a = 10 +5
fmt.Println(a)
a *= 2
fmt.Println(a)
}
3.6 其他运算符(地址 & 指针)
| 运算符 | 作用 |
|---|---|
& |
取变量内存地址 |
* |
解引用,取指针指向的值 |
示例
go
package main
import "fmt"
func main() {
a := 4
var ptr *int // 定义指针变量
ptr = &a // 取 a 的地址赋值给指针
fmt.Println("a 的地址:", ptr)
fmt.Println("a 的值:", *ptr) // 通过指针取值
}
3.7 运算符优先级
优先级由高到低 ,同优先级从左向右运算;括号 () 优先级最高,可手动改变运算顺序。
* / % << >> & &^+ - | ^== != < <= > >=&&||
示例(括号改变优先级)
go
package main
import "fmt"
func main() {
a, b, c, d := 20, 10, 15, 5
e := (a + b) * c / d
fmt.Println(e)
}