Go 指针

Go 中的指针允许我们直接操作内存地址。例如,我们可以使用指针访问和修改内存中变量的值。

在学习指针之前,让我们先了解一下 Golang 中的内存地址。


内存地址

当我们创建一个变量时,会为其分配一个内存地址来存储该变量的值。

在 Go 中,我们可以使用 & 运算符来访问内存地址。例如:

// Program to illustrate how memory address works

package main
import "fmt"

func main() {
  
  var num int = 5
  // prints the value stored in variable
  fmt.Println("Variable Value:", num)

// prints the address of the variable fmt.Println("Memory Address:", &num)
}

输出

Variable Value: 5
Memory Address: 0xc000018030

在上面的示例中,我们创建了变量 num,其值为 5。请注意打印语句

fmt.Println("Memory Address:", &num)

这里,&num 访问存储 num 变量的内存地址。


Go 指针变量

在 Go 中,我们使用指针变量来存储内存地址。例如:

var num int = 5

// create the pointer variable
var ptr *int = &num

这里,我们创建了一个名为 ptr 的指针变量,它存储了 num 变量的内存地址。

*int 表示该指针变量是 int 类型(存储 int 变量的内存地址)。

我们也可以创建其他类型的指针变量。例如:

// pointer variable of string type
var ptr1 *string

// pointer variable of double type
var ptr2 * float32

现在让我们看一个指针的实际工作示例。


示例:指针变量

我们可以将一个变量的内存地址赋给一个指针变量。例如:

// Program to assign memory address to pointer

package main
import "fmt"

func main() {

  var name = "John"
  var ptr *string

// assign the memory address of name to the pointer ptr = &name
fmt.Println("Value of pointer is", ptr) fmt.Println("Address of the variable", &name) }

输出

Value of pointer is 0xc00007c1c0
Address of the variable 0xc00007c1c0

在上面的示例中,我们创建了一个名为 ptrstring 类型指针变量。这里,指针变量和 name 变量的地址是相同的。

这是因为指针 ptr 存储了 name 变量的内存地址。

ptr = &name

获取 Golang 中指针指向的值

我们使用 * 运算符来访问指针指向的内存地址中的值。例如:

// Program to get the value pointed by a pointer

package main
import "fmt"

func main() {

  var name = "John"
  var ptr *string

  ptr = &name

// * to get the value pointed by ptr fmt.Println(*ptr) // John
}

这里,我们使用 *ptr 来访问指针指向的内存地址中存储的值。

由于指针存储了 name 变量的内存地址,因此我们得到输出值 "John"

注意:在上面的示例中,ptr 是一个指针,而 *ptr 不是。您不能也不应该这样做 *ptr = &name

* 被称为解引用运算符(在处理指针时)。它作用于指针并给出该指针中存储的值。


示例:Golang 中指针的工作原理

package main
import "fmt"

func main() {
  var num  int
  var ptr *int
    
  num = 22
  fmt.Println("Address of num:",&num)
  fmt.Println("Value of num:",num)

  ptr = &num
  fmt.Println("\nAddress of pointer ptr:",ptr)
  fmt.Println("Content of pointer ptr:",*ptr)
    
  num = 11
  fmt.Println("\nAddress of pointer ptr:",ptr)
  fmt.Println("Content of pointer ptr:",*ptr)
    
  *ptr = 2
  fmt.Println("\nAddress of num:",&num)
  fmt.Println("Value of num:",num)
}

输出

Address of num: 0xc000090020
Value of num: 22

Address of pointer ptr: 0xc000090020
Content of pointer ptr: 22

Address of pointer ptr: 0xc000090020
Content of pointer ptr: 11

Address of num: 0xc000090020
Value of num: 2

说明:Go 指针的工作原理

1. 声明变量

var num int
var ptr *int
The pointer variable and normal variable are declared
声明了指针变量和普通变量

在这里,我们创建了一个整型指针变量 ptr 和一个普通变量 num。这两个变量最初没有初始化,因此指针 ptr 不指向任何地址。

2. 给常规变量赋值

num = 22
A value is assigned to the regular variable.
给常规变量赋值

这会将 22 赋给变量 num。也就是说,22 存储在变量 num 的内存位置。

3. 将地址赋给指针

ptr = &num
The address of a regular variable is assigned to the pointer variable
将变量的地址赋给指针

这会将变量 num 的地址赋给指针 ptr

4. 更改变量的值

num = 11
The value of the variable is changed.
更改变量的值

这会将 11 赋给变量 num

5. 使用指针更改值

*ptr = 2
The value of the variable is changed using the pointer dereference operator.
使用指针更改变量的值

这会将指针 ptr 指向的内存位置的值更改为 2


常见问题

Golang 中的 Nil 指针

当我们声明一个指针变量但未对其进行初始化时,指针的值始终为 nil。例如:

// Program to illustrate the nil pointers

package main
import "fmt"

func main() {
  // declare a pointer variable
  var ptr *int
    
  fmt.Println("Value of pointer:", ptr)

}

输出

Value of pointer: <nil>

这里,指针 ptr 未初始化,因此它不指向任何地址。因此,指针的默认值始终为 nil。

使用 Golang new() 创建指针

我们也可以使用 new() 函数在 Go 中创建指针。例如:

// Program to create pointer using new() function

package main
import "fmt"

func main() {

  // create a pointer using new()
  var ptr = new(int)
  
  *ptr = 20
    
  fmt.Println(ptr)  // 0xc000016058
  fmt.Println(*ptr)  // 20

}

这里,在行 var ptr = new(int) 中,变量 ptr 成为一个 int 类型的指针。

当我们将 *ptr 赋给 20 时,ptr 在内存位置的值变为 20

创建不使用 * 运算符的指针

在 Go 中,我们也可以不使用 * 运算符来创建指针变量。例如:

package main
import "fmt"

func main() {

  var name = "John"

  // create pointer without *
  var ptr = &name

  fmt.Println("Value of ptr:", ptr)
  fmt.Println("Address of name:", &name)

}

输出

Value of ptr: 0xc0000101e0
Address of name: 0xc0000101e0

这里,我们直接将 &name(name 的地址)赋给了 ptr 变量。

在这种情况下,该变量是一个指针变量,尽管我们没有使用 * 运算符。

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战