Golang中嵌入指针与值的区别及应用
Golang中嵌入指针与值的区别及应用 在我的应用程序中,我将使用以下数据结构并传递它们。它们完全没有附加任何方法。在传递过程中不会被修改。
问题如下(从内存管理的角度来看):
- 所有嵌入的结构体是否应该使用指针?
- 我应该传递
Person的指针还是副本? - 如果我创建一个
Person的指针,但保持其内部所有嵌入的结构体为副本,当Person变量被传递时,是否会重新创建嵌入结构体的副本? - 您个人会怎么做?
谢谢
type Person struct {
Name string
ID string
OccupationUUID string
Marital bool
Friends Friend // pointer or not?
NextOfKins NextOfKin // pointer or not?
}
type Friend struct {
Nation string
School string
HouseNumber string
HouseID string
BuildingCode string
Age int
Identity string
Opening string
Active bool
Mode int
}
type NextOfKin struct {
KinType KinType // pointer or not?
}
type KinType struct {
KeyValue []KinTypeData // pointer or not?
}
type KinTypeData struct {
Type string
Name string
}
更多关于Golang中嵌入指针与值的区别及应用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
2 回复
从顶部开始,我会对前三个字段使用指针。对于 KinTypeData 切片,如果数据是为每个人创建的,我不会使用指针。如果数据是从另一个结构体引用的,并且需要同步更新,你也应该使用指针。
更多关于Golang中嵌入指针与值的区别及应用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
根据你的数据结构和需求,从内存管理角度分析:
1. 嵌入结构体是否应该使用指针?
不需要全部使用指针。在你的场景中:
- 结构体较小(Friend约100字节,NextOfKin更小)
- 数据不会被修改
- 需要频繁传递
建议方案:
type Person struct {
Name string
ID string
OccupationUUID string
Marital bool
Friends Friend // 使用值,因为Friend大小适中
NextOfKins NextOfKin // 使用值,结构很小
}
2. 应该传递Person指针还是副本?
传递指针更高效:
// 传递指针 - 推荐
func processPerson(p *Person) {
// 只读操作
fmt.Println(p.Name)
}
// 传递副本 - 不推荐(Person较大)
func processPersonCopy(p Person) {
fmt.Println(p.Name)
}
Person结构体包含多个字符串和嵌套结构,总大小可能超过200字节,传递指针(8字节)更高效。
3. 创建Person指针时嵌入结构体的行为
不会重新创建副本:
p := &Person{
Name: "John",
Friends: Friend{...}, // 这里创建了Friend的副本
NextOfKins: NextOfKin{...}, // 这里创建了NextOfKin的副本
}
// 传递p时,只传递8字节的指针
// Friend和NextOfKin的副本不会重新创建
anotherFunc(p)
4. 我的实现方案
type Person struct {
Name string
ID string
OccupationUUID string
Marital bool
Friends Friend
NextOfKins NextOfKin
}
type Friend struct {
Nation string
School string
HouseNumber string
HouseID string
BuildingCode string
Age int
Identity string
Opening string
Active bool
Mode int
}
type NextOfKin struct {
KinType KinType
}
type KinType struct {
KeyValue []KinTypeData // 切片本身就是引用类型(24字节)
}
type KinTypeData struct {
Type string
Name string
}
// 使用方式
func main() {
// 在堆上创建,通过指针传递
person := &Person{
Name: "Alice",
Friends: Friend{
Nation: "US",
Age: 30,
},
NextOfKins: NextOfKin{
KinType: KinType{
KeyValue: []KinTypeData{
{Type: "Parent", Name: "Bob"},
},
},
},
}
// 传递指针
processPerson(person)
}
func processPerson(p *Person) {
// 只读访问,不需要复制整个结构
fmt.Printf("Name: %s, Friend's Nation: %s\n",
p.Name, p.Friends.Nation)
}
关键点:
- Person使用指针传递(大小约200+字节)
- Friend和NextOfKin使用值嵌入(大小适中)
- KinType中的切片已经是引用类型,无需额外指针
- 所有字段都是只读的,无需担心并发修改

