Go语言中var、=与:=:设计思想、语法区别与使用场景

27 阅读5分钟

从变量的声明和赋值角度理解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 是新声明,合法 
}