惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
Google Developers Blog
小众软件
小众软件
The Cloudflare Blog
S
SegmentFault 最新的问题
美团技术团队
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
阮一峰的网络日志
阮一峰的网络日志
博客园 - 聂微东
V
Visual Studio Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
雷峰网
雷峰网
WordPress大学
WordPress大学
T
Tailwind CSS Blog
腾讯CDC
人人都是产品经理
人人都是产品经理
月光博客
月光博客
Microsoft Azure Blog
Microsoft Azure Blog
M
MIT News - Artificial intelligence
D
DataBreaches.Net
Apple Machine Learning Research
Apple Machine Learning Research
P
Proofpoint News Feed
J
Java Code Geeks
宝玉的分享
宝玉的分享

Chongxiの咖啡屋

深入聊聊apple设备间生态体验 - Chongxiの咖啡屋 Google相册迁移到iCloud分享 - Chongxiの咖啡屋 讲讲「万物皆虚,万事皆允」 - Chongxiの咖啡屋 舞萌DX 落雪查分器使用指南 - Chongxiの咖啡屋 现代人的刻舟求剑 - Chongxiの咖啡屋 舞萌DX错误码0010深度解析及处理方法 - Chongxiの咖啡屋 做了一个明日方舟-奇象巡展的像素画拼豆工具 - Chongxiの咖啡屋 舞萌DX国服封禁机制详解 - Chongxiの咖啡屋 舞萌开机网络自检底层技术说明,断网如何排查讲解 - Chongxiの咖啡屋 舞萌机台开机初始化进程详解 - Chongxiの咖啡屋 为什么喜欢音乐 反而不该去学音乐? - Chongxiの咖啡屋 从装逼到嘉豪:中国互联网的精神胜利进化史 - Chongxiの咖啡屋 游蒋介石故居:奉化溪口 - Chongxiの咖啡屋 钢铁雄心4 steam正版导入全DLC补丁 - Chongxiの咖啡屋 漫漫长夜全地图及介绍 - Chongxiの咖啡屋 记一次无需实名换绑米哈游通行证手机号 - Chongxiの咖啡屋 邮储银行万事达借记卡全面指南 - Chongxiの咖啡屋 x402:一个来自27年前的状态码能救活被ai榨干的「人类网站」吗 - Chongxiの咖啡屋 舞萌国人口大普查:全服玩家数据分析 - Chongxiの咖啡屋 家中网络「捉奸」记 - Chongxiの咖啡屋 中国移动PT927G光猫折腾指南:破解超级密码改桥接 - Chongxiの咖啡屋 最好用的Android邮件客户端推荐 - Chongxiの咖啡屋 如何验证对方是不是Chongxi我本人 - Chongxiの咖啡屋 三星S20系列刷入移植OneUI8流程 - Chongxiの咖啡屋 使用obisidian和git插件来完美管理静态博客 - Chongxiの咖啡屋 玩客云拆机教程 - Chongxiの咖啡屋 母语级英语的本质,不是英语 - Chongxiの咖啡屋 我用过最好用的Android桌面(启动器) - Chongxiの咖啡屋 1. 区块链基本知识 - Chongxiの咖啡屋 b站创作激励提现几乎无门槛了 - Chongxiの咖啡屋
Ch.03:Golang的变量 - Chongxiの咖啡屋
Chongxi · 2026-05-01 · via Chongxiの咖啡屋

程序运行的时候,数据需要一个地方存放。变量就是这个地方。你给一块内存起个名字,之后用这个名字来存取数据

变量是什么#

想象内存是一排格子,每个格子能存一个数据。变量就是给某个格子贴上标签,方便你找到它:

这行代码做了三件事:找一个空格子,把 20 写进去,贴上标签 age。之后你用 age,就能拿到 20

声明变量的方式#

Go 有两种声明变量的方式,各有适用场景。

:= 短声明#

PRTCL // GO

name := "Chongxi"

age := 20

height := 1.85

isAdmin := true

:= 是声明加赋值的简写,Go 会根据右边的值自动判断类型。"Chongxi" 是字符串,20 是整数,1.85 是浮点数,true 是布尔值。你不需要告诉 Go 类型是什么,它自己推断

:= 只能在函数内部用。 写在函数外面会报错:

PRTCL // GO

name := "Chongxi" // ❌ 报错,函数外不能用 :=

func main() {

name := "Chongxi" // ✅ 函数内可以

}

var 完整声明#

PRTCL // GO

var name string = "Chongxi"

var age int = 20

var 是声明变量的关键字,后面跟变量名,再跟类型,最后是值。比 := 啰嗦,但有它存在的理由:

var 可以在函数外用:

PRTCL // GO

var version string = "1.0.0" // ✅ 函数外可以

func main() {

fmt.Println(version)

}

var 可以只声明不赋值:

PRTCL // GO

var name string // 声明但不赋值

fmt.Println(name) // 输出 ""(空字符串)

:= 必须右边有值,var 可以先占个位置,后面再赋值

var 可以指定类型但不赋值,或者赋值但不指定类型:

PRTCL // GO

var age int // 指定类型,不赋值

var name = "Chongxi" // 不指定类型,赋值,Go 自动推断

两种方式怎么选#

日常写代码,函数内部几乎全用 :=,简洁。var 留给函数外的全局变量,或者需要先声明后赋值的情况

多变量声明#

同时声明多个变量,不用一行写一个:

PRTCL // GO

// := 方式

name, age := "Chongxi", 20

// var 方式

var (

name string = "Chongxi"

age int = 20

isAdmin bool

)

var 的括号写法适合声明一组相关的变量,代码看起来整齐

:= 的多变量写法有个特殊规则:左边至少有一个变量是新的,就可以用 :=

PRTCL // GO

name := "Chongxi"

name, age := "xi", 20 // ✅ age 是新变量,name 被重新赋值

如果左边全是已存在的变量,用 := 会报错:

PRTCL // GO

name := "Chongxi"

age := 20

name, age := "Chongxi", 21 // ❌ 报错,name 和 age 都已存在

赋值与重新赋值#

声明变量用 :=var,之后修改值用 =

PRTCL // GO

age := 18

fmt.Println(age) // 18

age = 20 // 重新赋值,注意是 = 不是 :=

fmt.Println(age) // 20

第二次不能再用 :=,否则报错:

PRTCL // GO

age := 18

age := 20 // ❌ 报错:no new variables on left side of :=

:= 是声明,= 是赋值,概念不同,符号不能混用

零值#

Go 里声明了变量但没有赋值,它不会是随机的垃圾值,而是有一个确定的默认值,叫零值

类型零值
int(整数)0
float64(浮点数)0.0
bool(布尔)false
string(字符串)""(空字符串)
指针、切片、mapnil

PRTCL // GO

var age int

var name string

var ok bool

fmt.Println(age) // 0

fmt.Println(name) // (空字符串,看不出来但确实是 "")

fmt.Println(ok) // false

零值的设计能让程序更安全,不会出现”我不知道这个变量现在是什么值”的情况

变量必须被使用#

Go 有一个让很多人第一次遇到时觉得好神经病的规定:声明了变量必须用,不用就报错

PRTCL // GO

func main() {

name := "Chongxi"

age := 20

fmt.Println(name)

// age 没有被使用

}

// 报错:age declared and not used

这个设计是刻意的。未使用的变量大概率是写错了,要么是遗留的垃圾代码。这是在强制你保持代码干净,养成习惯之后是好事

注意:这个规定只针对局部变量(函数内部的变量),函数外的全局变量不受限制

类型不能变#

Go 是静态类型语言,变量一旦确定类型,就不能存别的类型的值:

PRTCL // GO

age := 20

age = "qwq" // ❌ 报错:cannot use "hello" (type string) as type int

age 被推断为 int,就只能存整数,不能改成字符串。这和 Python 不一样,Python 的变量可以随时换类型

静态类型的好处是错误在编译阶段就能发现,不会等到程序跑起来才出问题

作用域#

变量不是在哪里都能用,它只在自己被声明的范围内有效,这个范围叫作用域

PRTCL // GO

func main() {

name := "Chongxi"

fmt.Println(name) // ✅ 可以用

}

// fmt.Println(name) // ❌ 报错,name 在 main 函数外不存在

花括号 {} 划定了作用域的边界,变量只在声明它的那对花括号里有效:

PRTCL // GO

func main() {

age := 18

if age >= 18 {

msg := "成年"

fmt.Println(msg) // ✅ 可以用

}

fmt.Println(msg) // ❌ 报错,msg 在 if 块外不存在

}

msg 是在 if 的花括号里声明的,出了这个花括号就不存在了

内层可以访问外层,外层不能访问内层:

PRTCL // GO

func main() {

name := "Chongxi"

if true {

fmt.Println(name) // ✅ 内层可以访问外层的 name

}

}

内层可以声明和外层同名的变量,会遮蔽外层:

PRTCL // GO

name := "Chongxi"

if true {

name := "xi" // 新声明,遮蔽了外层的 name

fmt.Println(name) // 输出 xi

}

fmt.Println(name) // 输出 Chongxi,外层的 name 没有变

这个现象叫变量遮蔽,是常见的坑,尤其在嵌套层级多的代码里,一不留神就用了错误的变量

全局变量#

声明在函数外部的变量叫全局变量,整个包内所有函数都能访问:

PRTCL // GO

var appName string = "MyApp"

func main() {

fmt.Println(appName) // ✅ 可以访问

}

全局变量不受”声明了必须使用”的限制,但不代表应该滥用,全局变量会让代码难以追踪和测试(笑),实际项目里能不用就不用,配置信息、常量这类才适合放全局

空白标识符 _#

有时候你不需要某个值,但语法要求你得接收它,这时候用 _ 丢掉:

PRTCL // GO

name, _ := getUserInfo() // 只要 name,不要第二个返回值

_ 是一个特殊的变量名,赋给它的值直接丢弃,不占用内存,也不受”必须使用”规则限制

小结#

  • 两种声明方式::= 用于函数内,简洁;var 可用于函数外,灵活
  • := 是声明加赋值,= 是单纯赋值,第二次修改变量用 =
  • 零值:整数 0,字符串 "",布尔 false
  • 变量必须被使用
  • Go 是静态类型语言,确定类型不能变
  • 作用域由花括号划定,内层能访问外层,反过来不行,内层同名变量会遮蔽外层
  • _ 用来丢弃不需要的值

下一篇我们会讲数据类型:整数、浮点、字符串、布尔等,Go 里的类型比你想的细