在 Go 语言中,使用指针方式实例化结构体有以下几个好处:
一、避免结构体值复制
当使用非指针方式实例化结构体并将其传递给函数或在不同地方使用时,会发生结构体值的复制。如果结构体较大,这种复制操作会消耗较多的内存和时间。而通过指针方式实例化结构体,传递的只是一个指向结构体的指针,避免了不必要的复制,提高了性能。
例如:
package main
import "fmt"
type Person struct {
Name string
Age int
}
func updatePerson(p Person) {
p.Age = 30
}
func updatePersonByPointer(p *Person) {
p.Age = 30
}
func main() {
p1 := Person{"Tom", 20}
updatePerson(p1)
fmt.Println(p1) // 输出 {Tom 20},Age 未被修改,因为函数中是值复制
p2 := &Person{"Jerry", 20}
updatePersonByPointer(p2)
fmt.Println(*p2) // 输出 {Jerry 30},Age 被修改成功,因为传递的是指针
}
二、可以修改结构体的内容
当使用非指针方式获取结构体变量时,得到的是结构体的副本,对副本的修改不会影响原始结构体。而使用指针方式,可以通过指针直接修改结构体的实际内容。
例如:
package main
import "fmt"
type Book struct {
Title string
}
func changeTitle(book Book) {
book.Title = "New Title"
}
func changeTitleByPointer(book *Book) {
book.Title = "New Title"
}
func main() {
b := Book{"Old Title"}
changeTitle(b)
fmt.Println(b) // 输出 {Old Title},Title 未被修改
changeTitleByPointer(&b)
fmt.Println(b) // 输出 {New Title},Title 被修改成功
}
三、支持 nil 值判断
指针类型的结构体变量可以为 nil,这在某些情况下可以方便地表示不存在或未初始化的状态,进行有针对性的处理。
例如:
package main
import "fmt"
type Student struct {
Name string
}
func printStudentInfo(s *Student) {
if s == nil {
fmt.Println("Student is nil")
} else {
fmt.Println(s.Name)
}
}
func main() {
var s *Student
printStudentInfo(s) // 输出 Student is nil
s1 := &Student{"Alice"}
printStudentInfo(s1) // 输出 Alice
}
(以上内容来自“豆包”大模型)