go语言中有一个很重要的概念指针,指针这个概念应该是从C语言中来的。
变量的地址
在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。系统根据变量的类型分配不同字节长度的空间。go语言中默认int类型在64位操作系统占用8个字节,内存中每一个字节都有一个编号,这个编号就是“地址”。
一个简单的实例如下:
var n2 int = 356 fmt.Printf("变量n2的类型为%T, 其占用字节大小为%d", n2, unsafe.Sizeof(n2)) fmt.Println("\n变量n2的内存地址单元为", &n2)
输出的结果如下:【操作系统为64位,int类型默认是int64因此是8字节的大小】
变量n2的类型为int, 其占用字节大小为8 变量n2的内存地址单元为 0xc0000540c0
内存地址单元是一串无符号十六进制数,毕竟地址不可能为负数。【所有变量的内存地址都是无符号十六进制】
编译完成程序运行的时候,操作系统是访问【0xc0000540c0】这个地址才访问到我们定义的变量的值。在程序中“&”符号表示 取址 操作,也就是查询某个变量的地址是多少。
访问n2这个变量的时候,我们可以像上面说到的通过访问【0xc0000540c0】这个地址块直接访问,也可以通过另外一种方式,就是把这个地址块的值放到另一个变量p中,要想获取变量n2的值,先从p中得到变量n2的地址,然后再去访问,如下的形式。
变量p中存的是变量n2的内存地址,通过变量p可以查找到变量n2。
通过p中的数值也就是变量n2的地址可以查找到变量n2,在go,c中将地址形象化的称作为指针。一个变量的地址就称作该变量的指针。
在上面的描述中,变量p是一个专门用来存储变量n2地址的变量,因此变量p称作指针变量。一个变量专门用来存储另一个变量的地址(即指针),则它称为“指针变量”。
定义指针变量
比较絮叨:上面说到,变量的指针就是变量的地址。存放变量地址的变量就是指针变量,它用来指向另一个变量。为了表示指针变量和它所指向的变量之间的联系,在程序中使用 “ * ”符号来表示这种“指向”关系。
在上面的例子中我们定义了变量n2,和指针变量p,那么*p就是指向n2的值。
声明一个指针变量形式如下: 【注意和c语言有点不同】
var name *type
如下实例:
var ap *int // 定义一个指针变量 var text int = 32 // 定义一个整型变量 ap = &text //把变量text的地址赋值给指针变量 fmt.Println("变量text的值为", text) fmt.Println("变量text的地址为", &text) fmt.Println("通过指针变量获得的text值为", *ap) fmt.Println("指针变量的值为", ap) fmt.Println("指针变量ap的地址为", &ap)
执行结果如下:【可以看到指针变量ap的值就是变量text的内存地址空间】
变量text的值为 32 变量text的地址为 0xc0000540d0 通过指针变量获得的text值为 32 指针变量的值为 0xc0000540d0 指针变量ap的地址为 0xc00007a020
go语言编译器为指针变量分配一个nil值,以防指针没有确切的地址分配,这是在变量声明的时候完成的。指定为nil值得指针称为nil指针。nil指针在标准库中定义的值为零。