Go中指针的介绍和使用
背景
指针是什么出现的意义是什么呢?
假设所有语言中都没有指针, 无论是显式的还是隐式的.
那么所有的变量传递都只能通过值Copy的方式了, 如果对象比较大的话, 就会比较浪费空间和性能. 如果还要求对传入的数据进行修改, 还需要将数据返回回去, 就变得比较复杂.
指针的出现就完美的解决了这些问题
简介
Go 是一门支持指针的编程语言,与其他编程语言的指针类似,Go 指针指向的是一个内存地址,可以通过指针间接访问和修改关联的变量。Go 指针还具有许多与其他编程语言不同的特性,下面我们来详细了解一下 Go 指针的相关知识。
指针的声明
在 Go 中,指针的声明与其他变量一样,只需要在变量名前面添加 *
符号即可,例如:
var ptr *int // 声明一个 int 类型的指针
在这个例子中,我们声明了一个名为 ptr
的指针,该指针指向 int 类型的变量,此时该指针的值为 nil
。
指针还可以使用取地址操作符 &
来获取变量的地址,例如:
var a int = 10 // 声明一个 int 类型的变量
var ptr *int = &a // 声明一个 int 类型的指针,并将其初始化为变量 a 的地址
在这个例子中,我们声明了一个名为 a
的 int 类型的变量,并使用 &
运算符获取其地址,然后将该地址赋值给 ptr 指针变量。
指针的间接引用
在 Go 中,指针变量可以通过 *
符号进行间接引用,从而访问它所指向的变量的值。例如:
var a int = 10 // 声明一个 int 类型的变量
var ptr *int = &a // 声明一个 int 类型的指针,并将其初始化为变量 a 的地址
fmt.Println(*ptr) // 输出 ptr 所指向的变量 a 的值,即 10
在这个例子中,我们声明了一个名为 a
的 int 类型的变量,并使用 &
运算符获取其地址并赋值给 ptr 指针变量。然后我们使用 *
符号对指针进行间接引用,即可输出该指针所指向的变量 a 的值。
指针的空值
在 Go 中,指针变量的空值为 nil
,它表示指针变量没有关联到任何内存地址。我们可以使用 nil
来检测一个指针是否为空,例如:
var ptr *int // 声明一个 int 类型的指针变量
if ptr == nil {
fmt.Println("ptr is null")
}
在这个例子中,我们声明了一个名为 ptr
的 int 类型的指针变量,并使用 nil
来检测它是否为空。由于这个指针变量没有关联到任何内存地址,所以输出的结果为 ptr is null
。
指向数组的指针
在 Go 中,我们可以使用指针来指向数组的元素,例如:
var arr [3]int = [3]int{1, 2, 3} // 声明一个含有 3 个元素的 int 类型数组
var ptr *int = &arr[0] // 声明一个 int 类型的指针,并将其初始化为数组的第一个元素的地址
fmt.Println(*ptr) // 输出数组的第一个元素的值,即 1
在这个例子中,我们声明了一个名为 arr
的 int 类型的数组,并使用 &
运算符获取其第一个元素的地址并赋值给指针变量 ptr
。然后我们使用 *
符号对指针进行间接引用,即可输出该指针所指向的数组的第一个元素的值。
指向结构体的指针
同样地,我们还可以使用指针来指向结构体的成员变量,例如:
type Person struct {
name string
age int
}
func main() {
var p Person = Person{
name: "Alice",
age: 18,
} // 声明一个 Person 类型的变量
var ptr *Person = &p // 声明一个 Person 类型的指针,并将其初始化为变量 p 的地址
fmt.Println((*ptr).name) // 输出指针所指向的变量 p 的 name 属性值,即 Alice
fmt.Println(ptr.age) // 使用指针直接访问变量 p 的 age 属性值,即 18
}
在这个例子中,我们声明了一个名为 p
的 Person 类型的变量,并使用 &
运算符获取其地址并赋值给指针变量 ptr
。然后我们使用 *
符号对指针进行间接引用,并访问该指针所指向的变量 p 的 name 属性值。还可以使用指针直接访问变量 p 的 age 属性值。
指针与函数
在 Go 中,函数与指针的关系非常密切,指针可以作为函数的参数或返回值传递。
我们可以使用指针参数来修改函数外部的变量,例如:
func addOne(ptr *int) {
*ptr++
}
func main() {
var a int = 10
addOne(&a) // 使用指针参数修改变量 a 的值
fmt.Println(a) // 输出修改后的变量 a 的值,即 11
}
在这个例子中,我们给函数addOne传入了一个名为 a
的 int 类型的指针, 并且进行了 ++ 操作, 发现其实结果作用于了main 里面的 a
Go语言指针小结
指针是Go语言中一个重要的概念,它可以方便地进行内存读写以及操作复杂数据类型。Go语言中的指针使用简单并且安全,需要注意的是,在使用指针时必须确保指针变量有指向有效的内存地址,否则会引发运行时错误。