理解 Go 语言中的指针

GolangGolangBeginner
立即练习

This tutorial is from open-source community. Access the source code

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

本实验将测试你对 Go 语言中指针的理解。指针用于在程序中传递对值和记录的引用。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL go(("Golang")) -.-> go/DataTypesandStructuresGroup(["Data Types and Structures"]) go/DataTypesandStructuresGroup -.-> go/pointers("Pointers") subgraph Lab Skills go/pointers -.-> lab-15494{{"理解 Go 语言中的指针"}} end

指针

问题在于通过两个函数 zerovalzeroptr 来理解指针与值相比是如何工作的。zeroval 有一个 int 类型的参数,所以参数会按值传递给它。zeroval 会得到 ival 的一个副本,这个副本与调用函数中的那个不同。相比之下,zeroptr 有一个 *int 类型的参数,这意味着它接受一个 int 指针。函数体中的 *iptr 代码随后会将指针从其内存地址解引用到该地址处的当前值。给解引用后的指针赋值会改变被引用地址处的值。

  • 你应该对 Go 语言有基本的了解。
  • 你应该知道如何在 Go 语言中定义和使用函数。
  • 你应该知道如何在 Go 语言中使用指针。
## `zeroval` 不会改变 `main` 函数中的 `i`,但
## `zeroptr` 会,因为它引用了那个变量的内存地址。
$ go run pointers.go
初始值: 1
zeroval: 1
zeroptr: 0
指针: 0x42131100

下面是完整代码:

// Go 语言支持 <em><a href="https://en.wikipedia.org/wiki/Pointer_(computer_programming)">指针</a></em>,
// 允许你在程序中传递对值和记录的引用。

package main

import "fmt"

// 我们将通过两个函数 `zeroval` 和 `zeroptr` 展示指针与值相比是如何工作的。`zeroval` 有一个
// `int` 类型的参数,所以参数会按值传递给它。`zeroval` 会得到 `ival` 的一个副本,这个副本与调用函数中的那个不同。
func zeroval(ival int) {
	ival = 0
}

// 相比之下,`zeroptr` 有一个 `*int` 类型的参数,这意味着它接受一个 `int` 指针。函数体中的 `*iptr` 代码随后会将指针从其
// 内存地址解引用到该地址处的当前值。给解引用后的指针赋值会改变被引用地址处的值。
func zeroptr(iptr *int) {
	*iptr = 0
}

func main() {
	i := 1
	fmt.Println("初始值:", i)

	zeroval(i)
	fmt.Println("zeroval:", i)

	// `&i` 语法给出 `i` 的内存地址,
	// 即指向 `i` 的指针。
	zeroptr(&i)
	fmt.Println("zeroptr:", i)

	// 指针也可以打印出来。
	fmt.Println("指针:", &i)
}

总结

在本实验中,你学习了如何在 Go 语言中使用指针。你还了解了向函数传递值和指针之间的区别。