4.1 Go结构体的指针
一、指针理解
在Go语言中,指针是学习结构体、方法和接口的基础,因为它们帮助你更高效地操作数据。简言之,指针是存储变量内存地址的变量。
-
指针本质是内存地址
指针存储的是数据在内存中的位置。 -
指针值本质是
uintptr
类型的整数值
指针值实际上是内存地址的数值化表示,底层是uintptr
类型。 -
实际使用时必须通过具体指针类型操作
具体指针类型确保类型安全,避免类型不匹配的问题。
有效的指针类型包括:
int
、string
、[]T
、[N]T
、*struct
等。
指针类型声明规范:
var (
numPtr *int // 整型指针声明
structPtr *User // 结构体指针声明
slicePtr *[]string // 切片指针声明
)
正确的取址方式:
val := 42
ptr := &val // 获取实例地址(注意:不是类型地址)
指针操作原则:
- 类型约束原则:指针类型必须与所指向的对象类型严格匹配。
- 实例化优先:禁止直接对类型取址(例如,
&int
是非法的),必须基于实例化的变量操作。 - 显式解引用:通过
*
运算符访问目标对象的值(例如,ptr != *ptr
)。
二、指针和类型的理解
指针和类型的理解
s2:=&Server{} //使用s2标识符记录实例&Server在内存中的地址。
//s2创建实例取地址
s2是指针,类型是*Server (指向Server的内存地址)
//s2是取的Server内存地址整数值,创建实例放在内存,s2是指针类型
package main
import "fmt"
type Server struct {
Id int
Sn string
Ip string
Hostname string
}
func main() {
s1 := Server{
Id: 101,
Sn: "E9527",
Ip: "192.168.101.102",
Hostname: "idc-beijing-xinglujianzhi-01-101",
}
//s2 := &s1 // 只能通过变量存储另一个变量的内存地址
s2 := &Server{} //使用s2表示记录Server实例&Server 存放在内存的地址
//S2是指针,类型是*Server (指向Server的内存地址)
s2.Sn = "A9527"
fmt.Println(s2.Sn)
fmt.Println(s1)
}
s2是取的Server内存地址,创建实例存放在内存,s2是指针类型
Go中可以通过实例标识符进行修改成员,也可以通过实例指针来修改成员
& 是一个变量,他存储的是另一个变量的内存地址。
三、复制类型解释
如同数组一样,是值类型。
赋值时、传实参(形参定义为结构体)、返回值时(结构体类型),都发生了值复制。有了完全一样的副本