1. 指针的基础知识
在Go语言中,指针是一个特殊的变量,它存储了另外一个变量的地址。通过指针,我们可以访问和修改另外一个变量。Go语言中使用&符号获取变量的地址,*符号访问地址所指向的变量。
1.1 指针的定义
定义指针变量时需要使用*符号,如下所示:
var ptr *int
上面的代码定义了一个整型变量指针ptr。需要注意的是,在定义指针变量时,需要指定指针所指向的变量类型。
1.2 获取指针的地址
获取变量的地址需要使用&符号,如下所示:
var a int = 10
var ptr *int
ptr = &a
上面的代码通过&符号获取变量a的地址,并将地址赋值给指针变量ptr。
1.3 访问指针所指向的变量
访问指针所指向的变量需要使用*符号,如下所示:
var a int = 10
var ptr *int
ptr = &a
fmt.Println(*ptr) // 10
上面的代码输出了指针ptr所指向的变量a的值。
1.4 指针的空值
在Go语言中,一个指针变量可以指向某个变量的地址,也可以指向空值(nil)。
var ptr *int
if ptr == nil {
fmt.Println("ptr is nil")
} else {
fmt.Println("ptr is not nil")
}
上面的代码输出ptr is nil,因为指针ptr未赋值。
2. 指针的应用
2.1 传递指针参数
当我们需要在函数内部修改某个变量的值时,可以通过指针来实现。在函数调用时,将变量的地址作为参数传递给函数。
func swap(x *int, y *int) {
var temp int
temp = *x
*x = *y
*y = temp
}
func main() {
var a int = 10
var b int = 20
fmt.Printf("交换前:a = %d, b = %d\n", a, b)
swap(&a, &b)
fmt.Printf("交换后:a = %d, b = %d\n", a, b)
}
上面的代码定义了一个swap函数,通过两个指针参数将两个变量的值交换。在main函数中,通过&符号获取变量a和b的地址,并将地址作为参数传递给swap函数。
2.2 使用指针变量访问数组元素
在Go语言中,数组名本身就是一个指向数组首元素的指针。
var arr = [3]int{10, 20, 30}
var ptr *[3]int = &arr
for i := 0; i < len(arr); i++ {
fmt.Printf("arr[%d] = %d\n", i, (*ptr)[i])
}
上面的代码定义了一个三个元素的数组arr,并定义了一个指向arr数组的指针ptr。在for循环中,通过指针变量访问了数组元素。
2.3 指针数组
在Go语言中,指针数组是一个数组,它的每个元素都是指针。
var a int = 10
var b int = 20
var c int = 30
var ptrArr [3]*int
ptrArr[0] = &a
ptrArr[1] = &b
ptrArr[2] = &c
for i := 0; i < len(ptrArr); i++ {
fmt.Printf("*ptrArr[%d] = %d\n", i, *ptrArr[i])
}
上面的代码定义了一个指针数组ptrArr,它包含三个指针,并且将三个变量的地址赋值给ptrArr数组元素。在for循环中,通过指针数组访问了变量的值。
2.4 指向指针的指针
在Go语言中,也可以定义指向指针的指针,如下所示:
var a int = 10
var ptr *int = &a
var ptrPtr **int = &ptr
fmt.Printf("a = %d\n", a) // 10
fmt.Printf("*ptr = %d\n", *ptr) // 10
fmt.Printf("**ptrPtr = %d\n", **ptrPtr) // 10
上面的代码定义了一个整型变量a,一个指向a的指针ptr,一个指向指针ptr的指针ptrPtr。通过打印三个变量的值,我们可以看到它们的值都是10。