当你用Go编写软件时,你将编写函数和方法。你可以将数据作为参数传递给这些函数。有时,函数需要数据的本地副本,而你希望原始数据保持不变。例如,如果你是一家银行,你有一个函数向用户显示根据他们选择的储蓄计划而产生的余额变化,你不希望在客户选择计划之前更改他们的实际余额;你只是想在计算中使用它。这被称为按值传递,因为你将变量的值发送给函数,而不是变量本身。
其他时候,你可能希望函数能够改变原始变量中的数据。例如,当银行客户向他们的账户存款时,您希望存款功能能够访问实际余额,而不是副本。在这种情况下,你不需要将实际数据发送给函数;你只需要告诉函数数据在内存中的位置。一种称为指针的数据类型保存的是数据的内存地址,而不是数据本身。内存地址告诉函数在哪里找到数据,而不是数据的值。你可以将指针而不是数据传递给函数,然后函数可以原地改变原始变量。这被称为引用传递,因为变量的值并没有传递给函数,只有它的位置。
在本文中,您将创建和使用指针来共享对变量内存空间的访问。
当你使用指向变量的指针时,有几个不同的语法元素需要你理解。第一个是和号(&
)的使用。如果你在变量名前放一个&符号,你是在声明你想要获取地址,或者指向该变量的指针。第二个语法元素是使用星号(*
)或解引用操作符。当你声明一个指针变量时,在变量名后面加上指针所指向的变量的类型,并以*
作为前缀,像这样:
var myPointer *int32 = &someint
这将创建myPointer
作为一个指向int32
变量的指针,并将指针初始化为someint
的地址。这个指针实际上并没有包含int32
,只是一个int32
的地址。
让我们看一下指向string
的指针。下面的代码声明了一个字符串的值和一个指向字符串的指针:
main.go
package main
import "fmt"
func main() {
var creature string = "shark"
var pointer *string = &creature
fmt.Println("creature =", creature)
fmt.Println("pointer =", pointer)
}
使用下面的命令运行这个程序:
go run main.go
运行这个程序时,它会打印出变量的值,以及变量的存储地址(指针地址)。内存地址是十六进制数,并不是人类可读的。在实践中,您可能永远不会输出内存地址来查看它。我们展示给你们是为了说明。因为每个程序在运行时都是在自己的内存空间中创建的,所以每次运行时指针的值都不一样,也和下面的输出不一样:
Outputcreature = shark
pointer = 0xc0000721e0
我们定义的第一个变量名为creature
,并将它设置为一个值为shark
的string
。然后我们创建了另一个名为pointer
的变量。这次,我们将pointer
变量的值设置为creature
变量的地址。我们使用&符号(’ & ')将值的地址存储在变量中。这意味着pointer
变量存储的是creature
变量的地址,而不是实际值。
这就是为什么当我们打印pointer
的值时,我们收到了0xc0000721e0
的值,这是creature
变量当前存储在计算机内存中的地址。
如果你想打印出pointer
变量指向的变量的值,你需要解引用该变量。下面的代码使用*
操作符解引pointer
变量并获取它的值:
main.go
package main
import "fmt"
func main() {
var creature string = "shark"
var pointer *string = &creature
fmt.Println("creature =", creature)
fmt.Println("pointer =", pointer)
fmt.Println("*pointer =", *pointer)
}
Outputcreature = shark
pointer = 0xc000010200
*pointer = shark
我们现在添加的最后一行解引了pointer
变量,并打印出存储在该地址的值。
如果你想修改存储在pointer
变量位置的值,你也可以使用解引用操作符:
main.go
package main
import "fmt"
func main() {
var creature string = "shark"
var pointer *string = &creature
fmt.Println("creature =", creature)
fmt.Println("pointer =", pointer)
fmt.Println("*pointer =", *pointer)
*pointer = "jellyfish"
fmt.