在go语言中访问指针或值
【摘要】 1 简介当使用允许访问指针值的编程语言(如 Java、C#、C/C++、Go 等)时,通常必须小心区分按值传递和按引用传递。 按值传递 按引用传递 将函数参数的值复制到另一个变量的机制 将实际参数传递给函数的机制 在函数中所做的更改不会反映在原始值...
1 简介
当使用允许访问指针值的编程语言(如 Java、C#、C/C++、Go 等)时,通常必须小心区分按值传递和按引用传递。
按值传递 按引用传递
将函数参数的值复制到另一个变量的机制 将实际参数传递给函数的机制
在函数中所做的更改不会反映在原始值中 在函数中所做的更改反映在原始值
复制实际参数 实际参数的地址传递给函数
函数获取实际内容的副本 函数访问原始变量的内容
需要更多内存 需要较少内存
需要更多时间,因为它涉及复制值 由于没有复制,因此需要的时间更少
分别看看结构体和指针数组在按值和按引用传递时的区别。Go 语言里这两个类型都有明显的行为差异,非常适合用来理解这个概念。
按值传递:使用按值传递时,函数参数的值将复制到内存中的另一个位置。在该函数中,仅访问或修改变量的副本。因此,原始值不受影响。
按引用传递:使用按引用传递时,将向该函数提供内存地址。换句话说,该函数可以访问 real 变量。
2 结构体(struct)
- 按值传递结构体
函数接收的是结构体的副本。修改不会影响原始结构体。
package main
import "fmt"
type Person struct {
name string
age int
}
func changePerson(p Person) {
p.age = 99
p.name = "Changed"
}
func main() {
p := Person{name: "Tom", age: 30}
changePerson(p)
fmt.Println("main:", p) // 输出: main: {Tom 30}
}
- 按引用传递结构体(传指针)
函数接收的是结构体的地址。修改会影响原始结构体。
func changePersonByRef(p *Person) {
p.age = 99
p.name = "Changed"
}
func main() {
p := Person{name: "Tom", age: 30}
changePersonByRef(&p)
fmt.Println("main:", p) // 输出: main: {Changed 99}
}
2 针数组(数组中存的是指针)
这是一个有点绕的场景,但也非常常见。我们来仔细看一下。
-
1 指针数组按值传递(传的是数组副本)
func changeArray(arr [2]*int) { x := 100 arr[0] = &x // 改变了指针指向 } func main() { a, b := 1, 2 arr := [2]*int{&a, &b} changeArray(arr) fmt.Println(*arr[0]) // 输出: 1,未改变原数组内容 }
虽然修改了 arr[0] 的指针,但只是副本,原数组没变。
-
-
指针数组按引用传递(传指针数组的指针)
func changeArrayByRef(arr *[2]*int) { x := 100 arr[0] = &x // 修改了原始数组中的指针 } func main() { a, b := 1, 2 arr := [2]*int{&a, &b} changeArrayByRef(&arr) fmt.Println(*arr[0]) // 输出: 100,改变了原数组内容 }
-
-
-
修改指针数组中指向的值(不改指向,只改值)
func modifyPointedValue(arr [2]*int) { *arr[0] = 999 } func main() { a, b := 1, 2 arr := [2]*int{&a, &b} modifyPointedValue(arr) fmt.Println(a) // 输出: 999,值被改变 }
-
虽然数组本身是按值传递,但指针指向的是同一个地址,对值的修改仍然生效。
3 小结
按值传递是指将函数参数值复制到另一个变量的机制,而按引用传递是指将实际参数传递给函数的机制。因此,这是按值传递和按引用传递之间的主要区别。
类型 是否需要指针来传引用 修改指针本身 修改指向的值
结构体 ✅ ✅ ✅
指针数组 ✅(如果改数组内容) ✅ 不需要
数组中的指针值 不需要 — ✅
如果需要处理较大的结构体,推荐用指针传参,减少复制开销。
参考:
https://go.dev/tour/basics/11 https://go.dev/doc/effective_go
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)