变量和常量

变量

声明、赋值变量

var name type

// 一次声明多个同一类型的变量
var a, b int

// 批量声明变量
var (
    a int
    b string
    c []float32
    d func() bool
    e struct {
        x int
    }
)

// 声明变量并赋值
var a int = 10 

// 声明变量但是没有初始化的,将会赋予指定数据类型
var b int // b = 0

// 变量类型自动推断
var age = 100 // 自动推断为int
fmt.Println("type=", reflect.TypeOf(age))

// := 简短声明
age := 10 // 自动推断类型为int

// 多变量赋值,a b 变量交换
var a int = 100
var b int = 200
b, a = a, b
fmt.Println(a, b)

匿名变量_

匿名变量的特点是一个下画线“”,“”本身就是一个特殊的标识符,被称为空白标识符。它可以像其他标识符那样用于变量的声明或赋值(任何类型都可以赋值给它),但任何赋给这个标识符的值都将被抛弃,因此这些值不能在后续的代码中使用,也不可以使用这个标识符作为变量对其它变量进行赋值或运算。使用匿名变量时,只需要在变量声明的地方使用下画线替换即可。例如:

堆和栈空间

栈:线性表,后进先出,适合可预知大小的变量分配

image-20210910160822165

堆:类似于往一个房间里摆放各种家具,家具的尺寸有大有小,分配内存时,需要找一块足够装下家具的空间再摆放家具。堆适合不可预知大小的内存分配,但是速度相对较慢,并且容易出现内存碎片

image-20210910160832864

变量存储在堆还是栈?

Go语言在编译期会帮助开发者判断变量应该放到堆上还是栈上(C++需要开发者自行判断),他的判断规则为:

  • 在编译期间堆变量进行逃逸分析

    • 没有发生:栈

    • 发生了:堆

变量逃逸分析

使用如下命令对上面代码进行内存分析:

变量逃逸分析:取地址符

执行go run -gcflags "-m -l" main.go的结果:

变量的作用域和生命周期

变量类型
定义位置
生命周期

全局变量

函数外部定义

等同于整个程序的运行周期

局部变量

函数内定义

创建变量的语句开始,到这个变量不再被使用为止

形参

函数签名定义

函数被调用的时候创建,函数调用结束后被销毁

变量逃逸会导致变量作用域的改变

常量

  • 用于存储不会发生改变的数据

  • 在编译时被创建,即使是函数内部的常量

  • 常量值只能是布尔型、数字型、字符串型

  • 定义常量的表达式必须是编译器可以进行求值的常量表达式

显示类型定义

隐式类型定义:将会由值推断类型

值必须是编译期间就可以确定的

批量声明常量

模拟枚举:iota常量生成器

最后更新于

这有帮助吗?