wzh

wzh

我想有那么一段时光,可以在面朝大海的房车里煮上一杯咖啡,看看曾写过的代码

关于 go 语言中的指针

本文发布于:2024-09-22

一、指针是一个指向另一个变量的地址的变量

go 语言指针采用 & 和 * 来操作指针。变量会将他们的值存储在计算机的随机存储器里面,而值的存储位置则是该变量的内存地址。通过使用 & 表示的地址操作符,我们可以得到指定变量的内存地址。

answer := 42
fmt.Println(&answer) // 打印 “0x1040c108”

地址操作符(&)提供值的内存地址,而它的反向操作解引用则提供内存地址指向的值。

answer := 42
fmt.Println(&answer) // "0x1040c108"

address := &answer

fmt.Println(*address) // 42

*int 中的星号表示这是一种指针类型。指针类型可以和其他的普通类型一样,出现在所有需要用到类型的地方,如变量声明、函数形参、放回值类型、结构字段类型等。

声明指针

canada := "Canada"

var home *string
fmt.Println("home is a %T\n", home) // 打印出“home is a string”

home = &canada
fmt.Println(*home) // 打印出“Canada”

 

二、指针的作用是指向

指向结构的指针

与字符串和数字不一样,在复合字面量的前面可以放置地址操作符(&)。

type person struct {
    name, superpower string
    age                         int
}

// timmy 变量指向 person 结构的内存地址
timmy := &person {
    name: "Timothy"
    age: 10
}

此外,访问字段时对结构进行解引用并不是必须的

timmy.superpower = "flying"  // 此处也可用(*timmy).superpower, 因为go 会为字段自动实施指针解引用,所以一般不这么写。

fmt.Println("%+v\n", timmy) // 打印 “&{name:Timothy superpower:flying age:10}”

指向数组的指针

跟结构的情况一样,我们也可以通过将地址操作符(&)放置在数组复合字面量的前面哎创建指向数组的指针,go 也为数组提供了自动解引用的特性。

切片和映射的复合字面量前面也可以放置地址操作符(&),但go 没有提供自动解引用的特性。

三、实现修改

通过指针可以实现跨函数和方法边界的修改。

将指针作为形参,go 语言的函数和方法都以传值方式传递形参,这意味着函数总是基于被传递实参的副本进行操作。当指针被传递至函数时,函数将接收到传入内存地址的副本,在此之后,函数就可以通过解引用内存地址来修改指针指向的值。

使用指针作为接收者的策略应该是始终如一的。如果一种类型的某些方法需要用到指针作为接收者,就应该为这种类型的所有方法都使用指针作为接收者。

内部指针

内部指针即是指向结构内部字段的指针。这一点可以通过在结构字段的前面放置地址操作符来完成。如 &player.status

四、隐式指针

并非所有修改都需要显示地使用指针,go 语言也会为一些内置的收集器暗中使用指针。

映射也是指针

切片指向数组

五、总结

1)指针存储的是内存地址

2)地址操作符(&)用于提供变量的内存地址

3)指针可以通过解引用(*)来获取或者修改被指向的值

4)指针的类型声明前面都带有星号(*),如 *int

5)使用指针可以跨越函数和方法的边界对值进行修改

6)指针与结构或者数组搭配使用时最为有用

7)映射和切片会隐式地使用指针

8)内部指针可以在无须将字段声明为指针的情况下指向结构中的字段

9)

wzh

wzh

我想有那么一段时光,可以在面朝大海的房车里煮上一杯咖啡,看看曾写过的代码

联络

  • EMail: qihui658[at]qq.com

标签

链接