Go 语言指针(Pointer)
                           
天天向上
发布: 2025-03-25 23:50:23

原创
815 人浏览过

Go 语言中的指针是变量的内存地址的引用,指针存储的是其他变量的地址,可以用来间接操作变量的值。与其他编程语言相比,Go 的指针相比 C 语言更加安全,因为 Go 不支持指针运算(如指针加减等)。


1. 指针基础

在 Go 中,指针是一个变量,它保存另一个变量的内存地址。通过指针,你可以访问该地址上的值。

1.1 定义指针

Go 中通过 * 来声明指针类型,指针的类型是它所指向变量的类型。

var ptr *int  // 声明一个指向 int 类型的指针
  • *int 表示指向 int 类型的指针。
  • ptr 是指针变量,它存储一个内存地址,指向一个 int 类型的值。

1.2 获取变量的地址

要获取一个变量的地址,可以使用 & 操作符,& 返回的是该变量的内存地址。

x := 58
ptr := &x  // ptr 存储 x 的内存地址
fmt.Println(ptr)   // 输出指针地址
fmt.Println(*ptr)  // 输出指针指向的值,即 58
  • &x 返回 x 的地址,存储在 ptr 中。
  • *ptr 用于访问 ptr 指向的值。

2. 解引用指针(Dereferencing)

解引用是通过指针访问其所指向的值。解引用操作符 * 被用于获取指针所指向的值。

x := 58
ptr := &x  // ptr 指向 x 的内存地址
fmt.Println(*ptr)  // 输出 58,解引用指针,访问指针指向的值

这里,*ptr 表示解引用 ptr,即获取 ptr 指向的值。


3. 指针作为函数参数

在 Go 中,指针常常用于函数参数传递,尤其是当你想让函数修改传入的变量时。传递指针比传递大量数据的副本更高效,特别是对于大对象或结构体。

3.1 传递指针给函数

package main

import "fmt"

func updateValue(ptr *int) {
    *ptr = 100  // 修改指针指向的值
}

func main() {
    x := 58
    fmt.Println("Before:", x)  // 输出:Before: 58
    updateValue(&x)  // 传递 x 的地址
    fmt.Println("After:", x)  // 输出:After: 100
}

在上述例子中,updateValue 函数通过指针修改了 x 的值。


4. 指针与数组、切片

指针常常与数组和切片一起使用。指针可以直接指向数组或切片中的元素,操作它们的值。

4.1 指向数组

指针可以指向数组的元素,通过指针间接修改数组的内容:

arr := [3]int{1, 2, 3}
ptr := &arr[0]  // 指向数组的第一个元素
*ptr = 100
fmt.Println(arr)  // 输出:[100 2 3]

4.2 指向切片

切片本身就是一个指向底层数组的引用,可以通过切片的指针来修改底层数组:

arr := []int{1, 2, 3}
ptr := &arr[0]  // 指向切片的第一个元素
*ptr = 100
fmt.Println(arr)  // 输出:[100 2 3]

5. newmake 与指针

Go 提供了 newmake 两个内建函数来创建对象,它们与指针相关,但用途有所不同。

5.1 new 函数

new 用于分配内存并初始化为零值,返回一个指向该内存的指针。

ptr := new(int)  // 创建一个指向 int 类型的指针
fmt.Println(*ptr)  // 输出:0,因为 new 初始化为零值
*ptr = 58
fmt.Println(*ptr)  // 输出:58
  • new(int) 创建了一个指向 int 类型的指针,内存被初始化为零值。

5.2 make 函数

make 用于创建切片、映射(map)和通道(channel),它返回的是切片、映射或通道,而不是指针。与 new 不同,make 不返回一个指向新对象的指针。

slice := make([]int, 5)  // 创建一个长度为 5 的切片
fmt.Println(slice)  // 输出:[0 0 0 0 0]

make 返回一个初始化过的切片,映射或通道,而 new 返回的是指向零值的指针。


6. 指针的零值

指针的零值是 nil,表示该指针没有指向任何有效的内存地址。

var ptr *int  // ptr 默认为 nil
fmt.Println(ptr)  // 输出:<nil>

如果你尝试解引用一个 nil 指针,Go 会抛出运行时错误(panic)。


7. 指针的用途总结

  • 传递大对象:通过指针传递对象可以避免复制大量数据。
  • 函数修改参数:通过传递指针,函数可以修改调用者的变量。
  • 内存管理:指针用于动态内存分配,new 可以用于创建指针。
  • 切片与数组:指针常用于操作切片和数组。

8. 指针总结

  • 指针是存储内存地址的变量,可以用来间接访问和修改值。
  • Go 中的指针可以通过 * 获取指针所指向的值,通过 & 获取变量的内存地址。
  • 指针是函数参数传递时修改数据的常见方式,尤其用于传递大数据结构。
  • Go 使用 newmake 来分配内存和创建对象,但它们有不同的用途和行为。

🔹 参考资料

发表回复 0

Your email address will not be published. Required fields are marked *