从变量的声明和赋值角度理解var、=与:=
graph TD
声明 --> var
赋值 --> var
声明+赋值 --> var
声明+赋值 --> :=
赋值 --> =
设计思想
我们在代码中创建变量时,实际上有2个步骤,首先声明变量,之后给变量赋值。对应到底层,就是先在内存中给变量分配一个空间(声明),之后在这空间存储一个值(赋值)。
在GO中,我们可以用var关键字来声明变量,并赋值
// 声明变量,并指定类型,此时可以不赋值
var age int // 整型,默认值 0
var name string // 字符串,默认值 ""
var isStudent bool // 布尔型,默认值 false
// 自动推导类型(由于有自动推导,必须赋值,否则无法推导)
var height = 175.5 // 自动推导为 float64
var country = "中国" // 自动推导为 string
var isOpen = true // 自动推导为 bool
//用var()代码块一次性声明多个变量
var (
id int = 1001
score float64 = 98.5
phone string
married bool
)
//在一行中声明多个变量
var a, b, c int // 声明多个 int 变量,默认零值
var x, y, z = 10, 20, 30
var city, province = "北京", "北京" // 声明多个变量并赋值,自动推导类型
在自动推导类型时,由于这种写法太长,所以我们用:=来简化语法。
注:
:=只能在函数内使用。所以全局变量只能用var声明
// := 是短变量声明,只能在函数内部使用(必须赋值,否则无法推导类型)
height := 175.5 // 自动推导为 float64
country := "中国" // 自动推导为 string
isOpen := true // 自动推导为 bool
简单来讲,var可负责声明或声明+赋值,=只负责赋值,而:=同时负责声明+赋值。
核心思想到这里就讲明了,下面是使用场景和对比。
使用场景
2.1 var 关键字
适用于所有场景的变量声明,尤其是全局变量声明、需要明确指定变量类型、仅声明不赋值(零值初始化)、批量声明多个变量的场景,灵活性更高。
例1:全局变量声明(必用var)
var globalId int = 1001 // 全局变量,可在所有函数中使用
例2:明确指定变量类型(避免类型推导偏差)
var money int64 = 100000 // 明确声明为int64类型,防止自动推导为int
例3:仅声明不赋值(零值初始化)
var isLogin bool // 零值为false,后续按需赋值
例4:批量声明多个变量
var (
name string = "张三"
age int = 20
score float64
)
2.2 := 短变量声明
仅适用于函数内局部变量,适合无需明确类型、需快速完成“声明+赋值”的场景,尤其适合多变量声明+部分复用的高频场景(如val, err := func()),语法简洁高效。
例1:函数内快速声明+赋值(简化var自动推导写法)
func main() {
username := "李四"
age := 22
}
例2:多变量声明+部分复用旧变量(独有功能)
func main() {
var num = 10
num, str := 20, "hello" // 复用num,这里必须声明新变量,否则报错
}
例3:高频场景(函数返回值声明+赋值)
func main() {
val, err := fmt.Println("测试") // 声明val和err两个变量,接收函数返回值
}
2.3 = 赋值符号
仅用于给已声明的变量(全局、局部均可)赋值,不具备声明变量的功能,无使用范围限制,只需保证左边变量已存在。
例1:给全局变量赋值
var globalNum = 10
func main() {
globalNum = 20 // 给已声明的全局变量赋值
}
例2:给局部变量赋值(var声明后)
func main() {
var localNum int
localNum = 30 // 给已声明的局部变量赋值
}
例3:给局部变量赋值(:=声明后)
func main() {
str := "test"
str = "hello" // 给已声明的局部变量重新赋值
}
= VS := 对比表格
对比表格如下
| 过程 | var 关键字 | 赋值符号 = | 短变量声明 := |
|---|---|---|---|
| 声明过程 | 可单独声明(无需赋值,零值初始化);可声明多个变量;不可重复声明新变量 | 不具备声明功能,仅能给已声明变量赋值 | 必须声明新变量(否则报错);仅能在函数内声明;不可重复声明同一变量 |
| 赋值过程 | 可在声明时同步赋值,也可先声明后用=赋值 | 核心功能,仅负责赋值;需保证左边变量已声明;无范围限制 | 声明时必须同步赋值(无法单独赋值);可给旧变量赋值(前提是有新变量声明) |
| 声明+赋值过程 | 支持(如var a = 10),可指定类型或自动推导类型;灵活度高 | 不支持,仅能单独赋值,无法完成声明 | 核心功能(语法糖),一行完成;自动推导类型;仅局部可用 |
| 特殊注意 | 不可重复声明同一变量,可批量声明 | 无声明功能,不可给未声明变量赋值 | 声明新变量时,可给旧变量重新赋值(不冲突) |
注:同一个变量不可重复声明,但:=声明新变量时也可给旧变量赋值。例:
package main
import "fmt"
func main() {
a := 10 // 第一次声明并赋值 a,短变量声明
fmt.Println(a) // 10
// 错误写法:重复声明同一个变量
// a := 20 // 报错:no new variables on left side of :=
a = 20 // 正确:直接赋值
fmt.Println(a) // 20
// 关键用法:左边有至少一个新变量时,:= 可以给旧变量赋值
a, b := 30, 40
fmt.Println(a, b) // 30 40
// a 是重复赋值,b 是新声明,合法
}