【Go 语言圣经】程序结构

引用
本文内容来自:Go语言圣经(中文版)

环境配置:

  • 系统:Windows11
  • 编辑器:vscode
注意
本文假设你已经安装了Go并配置好相关环境,如果你还没有安装Go,请前往Go官方网站进行下载安装

🍒 变量

变量是一种使用方便的占位符,用于引用计算机内存地址。

指针

变量有时候被称为可寻址的值。即使变量由表达式临时生成,那么表达式也必须能接受&取地址操作。

每次我们对一个变量取地址,或者复制指针,我们都是为原变量创建了新的别名。

1
2
3
4
5
6
7
8
func incr(p *int) int {
    *p++ // 非常重要:只是增加p指向的变量的值,并不改变p指针!!!
    return *p
}

v := 1
incr(&v)              // side effect: v is now 2
fmt.Println(incr(&v)) // "3" (and v is 3)

指针特别有价值的地方在于我们可以不用名字而访问一个变量,但是这是一把双刃剑:要找到一个变量的所有访问者并不容易,我们必须知道变量全部的别名(译注:这是Go语言的垃圾回收器所做的工作)。

new函数

表达式new(T)将创建一个T类型的匿名变量,初始化为T类型的零值,然后返回变量地址,返回的指针类型为

1
2
3
4
p := new(int)   // p, *int 类型, 指向匿名的 int 变量
fmt.Println(*p) // "0"
*p = 2          // 设置 int 匿名变量的值为 2
fmt.Println(*p) // "2"

变量的生命周期

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
var global *int

func f() {
    var x int
    x = 1
    global = &x
}

func g() {
    y := new(int)
    *y = 1
}

f函数里的x变量必须在堆上分配,因为它在函数退出后依然可以通过包一级的global变量找到,虽然它是在函数内部定义的;用Go语言的术语说,这个x局部变量从函数f中逃逸了。

相反,当g函数返回时,变量*y将是不可达的,也就是说可以马上被回收的。因此,y并没有从函数g中逃逸,编译器可以选择在栈上分配y的存储空间(译注:也可以选择在堆上分配,然后由Go语言的GC回收这个变量的内存空间),虽然这里用的是new方式。

0%