Golang中嵌入指针与值的区别及应用

Golang中嵌入指针与值的区别及应用 在我的应用程序中,我将使用以下数据结构并传递它们。它们完全没有附加任何方法。在传递过程中不会被修改。

问题如下(从内存管理的角度来看):

  1. 所有嵌入的结构体是否应该使用指针?
  2. 我应该传递 Person 的指针还是副本?
  3. 如果我创建一个 Person 的指针,但保持其内部所有嵌入的结构体为副本,当 Person 变量被传递时,是否会重新创建嵌入结构体的副本?
  4. 您个人会怎么做?

谢谢

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中的切片已经是引用类型,无需额外指针
  • 所有字段都是只读的,无需担心并发修改
回到顶部