指针

本节我们介绍下Golang中的指针,并了解下Golang中的指针跟其他编程语言比如C、C++之间的区别。

什么是指针

指针是一个存储了其他变量的内存地址的变量。这句话有点绕,怎么理解呢?其实很简单。指针其实也是一个变量,只要是变量就会存储某个值,指针存储的值比较特殊,是另外一个变量的内存地址。

0ab351c10442374f8e6509af21c1fa7e.png

看一下前面这张示例图,变量b存储的值为156,其在内存中的地址为0x1040a124。变量a存储的值是变量b的地址。因此这里变量a指向变量b,变量a是变量b的指针。

声明一个指针变量

一个指向T类型数据的指针变量声明格式为*T。 我们写个函数来声明一个指针变量。

package main

import "fmt"

func main() {
    b := 255
    var a *int = &b
    fmt.Printf("Type of a is %T\n", a)
    fmt.Println("Address of b is", a)
}

Go Playground在线运行 这里的&运算符用来获取一个变量的地址。我们将变量b的地址赋值给指针变量a,其数据类型为*int。这时指针a指向变量b。当我们打印指针变量a的值时,其实打印的是变量b的地址。该程序输出如下:

变量b可能存在于内存中的任何地址,因此你的打印结果可能跟我的不同。

指针变量的零值

指针变量的零值为nil

Go Playground在线运行 这里指针变量b的初始值为nil,然后我们给其赋值变量a的地址。执行结果如下:

通过new函数来创建指针

Golang提供了一个便捷的new函数用来创建指针。new函数的入参为类型T,返回值为一个指向该类型零值变量的指针。有点绕,我们举个例子看下。

Go Playground在线运行 这里我们通过new函数创建了一个指向一个临时的int类型数据的指针,该临时数据分配的值为对应类型的零值,比如这里即为int类型的零值0。该程序执行结果如下:

指针解除引用

所谓的指针解引用指的是访问指针指向的变量的值。指针a解引用的语法为*a

下面通过一个例子来了解下:

Go Playground在线运行 这里我们通过指针a解引用来访问其指向的变量b的值。执行结果如下:

下面修改下前面的程序,我们通过指针来修改变量b的值:

Go Playground在线运行 这里我们通过*a++将指针a指向的变量加1,由于a指向的变量为b,因此b变量的值变为256。该程序输出如下:

指针作为函数入参

Go Playground在线运行 这里我们将指向变量a的指针变量b作为入参传递给函数changechange函数内部通过指针解引用改变了变量a的值。输出结果为:

指针作为函数返回值

Golang中允许返回指向局部变量的指针,如果一个指向局部变量的指针作为函数返回值,那么Golang编译器会在堆内存上分配该局部变量。

Go Playground在线运行 这里函数hello将局部变量i的指针作为函数返回值。在其他诸如C和C++之类的编程语言中这种写法是错误的,因为变量i是局部变量,一旦函数返回,局部变量就访问不到了。但是Golang会在局部变量初始化时检查下是否会在函数外部被引用,比如这里的局部变量i,其指针作为函数返回值返回出去,因此会在函数外部引用,这是Golang就将该局部变量分配在堆内存中。该程序执行结果为:

尽量避免数组指针,多用切片

如果我们把一个指向数组的指针作为函数入参,那么可以在函数内部通过该指针来修改数组内部值,并且该修改在函数外也是可见的。

Go Playground在线运行 这里将数组a的指针作为函数modify的入参,并通过该指针来将其指向的数组的第一个元素的值改为90。输出为:[90 90 91]

(*a)[x]可以简写为a[x],因此前面程序中的(*arrP)[0]可以简写为arrP[0]

Go Playground在线运行 执行结果不变,输出:[90 90 91]

尽管这种通过数组指针来在函数内部修改数组是行得通的,但是Golang中一般不这么用,Golang中比较惯用的用法一般是使用切片(slice)。

Go Playground在线运行 这里我们将一个切片a[:]作为函数modify的入参,然后在函数内部将该切片的第一个元素修改为90。该程序输出:[90 90 91]

因此,我们在Golang中,尽量避免数组指针,而应该多用切片

Golang不支持指针运算

Golang跟C和C++不同,不支持指针运算,这其实在一定程度上降低了Golang这门编程语言的复杂度。

Go Playground在线运行

该程序执行会报错:

Last updated

Was this helpful?