一个指针变量可以指向任何一个值的内存地址,它所指向的值的内存地址在 32 和 64 位机器上分别占用 4 或 8 个字节,占用字节的大小与所指向的值的大小无关。当一个指针被定义后没有分配到任何变量时,它的默认值为 nil。指针变量通常缩写为 ptr。
每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。Go语言中使用在变量名前面添加&
操作符(前缀)来获取变量的内存地址(取地址操作),格式如下:
ptr := &v // v 的类型为 T
其中 v 代表被取地址的变量,变量 v 的地址使用变量 ptr 进行接收,ptr 的类型为*T,称做 T 的指针类型,*代表指针,一般*T 会被用作引用传参
从指针变量获取指针所指向的值:
当使用&
操作符对普通变量进行取地址操作并得到变量的指针后,可以对指针使用*
操作符,也就是指针取值,代码如下。
package main import ( "fmt" ) func main() { // 准备一个字符串类型 var house = "Malibu Point 10880, 90265" // 对字符串取地址, ptr类型为*string ptr := &house // 打印ptr的类型 fmt.Printf("ptr type: %T\n", ptr) // 打印ptr的指针地址 fmt.Printf("address: %p\n", ptr) // 对指针进行取值操作 value := *ptr // 取值后的类型 fmt.Printf("value type: %T\n", value) #打印取值后 value 的类型。 // 指针取值后就是指向变量的值 fmt.Printf("value: %s\n", value) #打印 value 的值 }
运行结果:
ptr type: *string address: 0xc0420401b0 value type: string value: Malibu Point 10880, 90265
使用指针修改值:
package main import "fmt" // 交换函数 func swap(a, b *int) { // 取a指针的值, 赋给临时变量t t := *a // 取b指针的值, 赋给a指针指向的变量 *a = *b // 将a指针的值赋给b指针指向的变量 *b = t } func main() { // 准备两个变量, 赋值1和2 x, y := 1, 2 // 交换变量值 swap(&x, &y) // 输出变量值 fmt.Println(x, y) }
运行结果:
2 1
*
操作符作为右值时,意义是取指针的值,作为左值时,也就是放在赋值操作符的左边时,表示 a 指针指向的变量。其实归纳起来,*
操作符的根本意义就是操作指针指向的变量。当操作在右值时,就是取指向变量的值,当操作在左值时,就是将值设置给指向的变量。
创建指针的另一种方法——new() 函数
Go语言还提供了另外一种方法来创建指针变量,格式如下:
new(类型)
一般这样写:
str := new(string) *str = "Go语言教程" fmt.Println(*str)
new() 函数可以创建一个对应类型的指针,创建过程会分配内存,被创建的指针指向默认值。