Go语言指针机制解析
理解Go语言中的指针需要掌握三个核心要素:内存地址定位、类型标识以及值访问机制
内存地址与类型标识
程序运行时每个数据实体都会占据特定内存空间,通过地址标识符可定位存储位置。Go语言通过&运算符获取变量地址,所有基础数据类型(整型、浮点型、布尔型、字符串、数组、结构体)均存在对应指针类型,例如*int、*string等。
地址获取语法结构如下:
var v T
var ptr *T
ptr = &v // 通过&运算符获取变量v的内存地址
实例演示:
func main() {
num := 50
addr := &num
fmt.Printf("数值:%d 地址:%p\n", num, &num) // 输出数值:50 地址:0xc00001a078
fmt.Printf("指针:%p 类型:%T\n", addr, addr) // 指针:0xc00001a078 类型:*int
fmt.Println(&addr) // 输出指针地址:0xc00000e018
}
指针解引用
通过&运算符获取变量地址后,可使用*运算符进行解引用操作获取实际值,具体实现如下。
func main() {
value := 50
ptr := &value // 获取变量地址
fmt.Printf("指针类型:%T\n", ptr)
decoded := *ptr // 解引用操作
fmt.Printf("解引用类型:%T\n", decoded)
fmt.Printf("解引用值:%v\n", decoded)
}<br></br><br></br>输出结果:
指针类型:*int
解引用类型:int
解引用值:50
核心概念总结:&运算符用于获取变量地址,*运算符用于访问指针指向的值,二者构成完整的地址操作体系。
地址操作特性
- 原始变量通过
&运算生成指针变量 - 指针变量存储的是内存地址信息
- 指针变量通过
*运算获取原始数据值
函数参数传递机制
func updateValue(x int) {
x = 200
}
func updatePointer(x *int) {
*x = 200
}
func main() {
data := 50
updateValue(data)
fmt.Println(data) // 输出50
updatePointer(&data)
fmt.Println(data) // 输出200
}
内存分配函数
new函数
内置函数new用于类型实例化,其定义如下:
func new(Type) *Type
该函数返回指定类型的指针,初始化值为对应类型的零值。示例:
func main() {
intPtr := new(int)
boolPtr := new(bool)
fmt.Printf("%T\n", intPtr) // *int
fmt.Printf("%T\n", boolPtr) // *bool
fmt.Println(*intPtr) // 0
fmt.Println(*boolPtr) // false
}
make函数
用于初始化引用类型数据结构,支持slice、map和channel的创建。其定义为:
func make(t Type, size ...IntegerType) Type
该函数直接返回引用类型实例,无需额外指针转换。典型用法:
func main() {
mp := make(map[string]int, 10)
mp["test"] = 100
fmt.Println(mp)
}
new与make差异对比
两者均用于内存分配:
make专用于slice、map、channel的初始化,返回引用类型实例;
new适用于所有类型,返回类型指针,初始化值为零值。