Go指针方式实例化结构体的好处

73 阅读2分钟
  1. 性能优化

    • 避免数据复制:当结构体较大时,值传递会复制整个结构体的数据。例如,假设有一个包含大量字段的结构体LargeStruct,如果通过值传递的方式来实例化和使用它,每次传递都会复制这个结构体的所有数据。

type LargeStruct struct {
    // 假设这里有很多字段,例如一个长度为1000的数组
    Data [1000]int
    // 还有其他字段
    OtherField string
}
func useValue(l LargeStruct) {
    // 这里只是一个示例操作,比如打印结构体中的一个字段
    println(l.OtherField)
}
func usePointer(l *LargeStruct) {
    println(l.OtherField)
}
func main() {
    // 实例化结构体
    ls := LargeStruct{
        OtherField: "example",
    }
    useValue(ls)
    usePointer(&ls)
}
  • 在上述代码中,useValue函数是通过值传递LargeStruct,这会导致LargeStruct的数据被复制一份。而usePointer函数通过指针传递,只传递了结构体的内存地址,避免了大量数据的复制,在处理大型结构体时可以显著提高性能。

  1. 修改原结构体方便

    • 直接修改:通过指针实例化结构体后,可以方便地修改原结构体的值。假设要实现一个函数来更新Person结构体的年龄。

type Person struct {
    Name string
    Age  int
}
func updateAge(p *Person, newAge int) {
    p.Age = newAge
}
func main() {
    p := &Person{
        Name: "Bob",
        Age:  25,
    }
    updateAge(p, 26)
    println(p.Age)
}
  • 在这个updateAge函数中,通过指针p可以直接修改传入的Person结构体的Age字段。如果使用值传递的方式,就需要返回修改后的结构体,并且在调用函数的地方重新接收这个结构体,这样会使代码变得复杂。

  1. 共享数据结构

    • 多个指针指向同一结构体:可以有多个指针指向同一个结构体实例。这在多个函数或模块需要共享和操作同一个数据结构时非常有用。例如,有一个游戏中的玩家结构体Player,游戏的不同模块(如玩家状态管理模块、玩家装备管理模块等)可能都需要访问和修改这个玩家结构体。

type Player struct {
    Name    string
    Health  int
    Level   int
    // 其他玩家相关属性
}
func updateHealth(player *Player, damage int) {
    player.Health -= damage
}
func updateLevel(player *Player, exp int) {
    // 假设这里有根据经验值更新等级的逻辑
    player.Level += 1
}
func main() {
    player := &Player{
        Name:    "Alice",
        Health:  100,
        Level:   1,
    }
    updateHealth(player, 10)
    updateLevel(player, 100)
    // 可以看到,不同的函数可以通过同一个指针来修改玩家结构体的不同属性
    println(player.Health)
    println(player.Level)
}
  • 这样,不同的函数(updateHealthupdateLevel)可以通过共享的指针来操作同一个Player结构体,实现对玩家状态的综合管理。