go-值传递和引用类型
- 调用函数时,Go 会把实参的值复制一份传给形参。无论参数类型是什么,底层规则都是值传递
- 参数传递方式:始终是值传递, 区别在于:不同类型的“值”包含的信息不同。
| 类型 | 复制的内容 | 函数内修改是否影响调用方 |
|---|---|---|
int、float64、bool | 实际数据 | 不影响 |
string | 字符串描述值 | 重新赋值不影响 |
struct | 所有字段的副本 | 普通字段不影响 |
*T | 地址值的副本 | 可通过地址修改原对象 |
[]T | 指针、长度、容量 | 修改已有元素通常会影响;修改长度不会自动回传 |
map[K]V | map 描述信息的副本 | 增删改元素通常会影响 |
chan T | channel 描述信息的副本 | 收发数据作用于同一个 channel |
interface{} any | 动态类型和值的副本 | 取决于动态值是值还是指针 |
指针理解
Go 永远是值传递,只不过传指针时,复制的这个值恰好是“内存地址”
- 复制地址,但可以修改原对象
- 传入指针时,复制的仍然是指针本身,也就是地址的副本:
- 指针传递:传指针是复制的是地址,通过地址仍能改到原结构体
指针语法
&变量= 取地址,标识取这个变量的内存地址*类型= 声明指针类型,表示指向该类型的指针*指针= 解引用,通过指针找到它指向的原始值 (拿到原始值)
a := 10
var p *int = &a
fmt.Println(p) // a 的内存地址
fmt.Println(*p) // 10
// 修改原始值*p = 20
fmt.Println(a) // 20