
结构体切片指针与结构体数组指针:细致比较
在Go语言中,处理包含结构体的切片和数组时,指针的使用至关重要。本文将深入探讨两种常见的函数签名,并阐明其关键区别:
type Widget struct {
id int
attrs []string
}
func doSomething(ss *[]Widget) {}
func doOtherThing(sp []*Widget) {}
*`doSomething(ss []Widget)`**
- 参数
ss是一个指向[]Widget切片的指针。 - 函数内部,
ss直接指向包含Widget结构体元素的切片内存地址。 - 对该切片进行的任何修改(例如,添加、删除或修改元素)都会直接影响到外部调用的切片。 这体现了指针的特性:修改指针指向的值。
*`doOtherThing(sp []Widget)`**
- 参数
sp是一个*Widget指针的切片,即一个包含多个Widget结构体指针的切片。 - 函数内部,
sp包含的是一系列指向各个Widget结构体内存地址的指针。 - 对
sp中的指针所指向的Widget结构体进行修改会影响到外部调用的结构体。但是,如果在函数内部修改了sp切片本身(例如,改变切片的长度或重新分配),则不会影响外部调用的切片。 这因为sp本身是一个局部变量,只是外部切片的一个副本。
总结:
*[]Widget 传递的是切片本身的地址,函数内对切片内容的任何修改都会反映到函数外部。而 []*Widget 传递的是一系列指向结构体的指针,修改结构体内容会影响外部,但修改指针切片本身不会影响外部。 选择哪种方式取决于是否需要在函数内部修改切片本身的结构(例如,添加或删除元素)。如果只需要修改结构体内容,则两种方式都可以;如果需要修改切片结构,则必须使用 *[]Widget。










