

新闻资讯
技术学院传[]T无法修改原切片,因其header按值传递;需传[]T或返回新切片,或用[]T批量修改字段。
在 Go 中,要通过指针高效更新结构体切片,关键在于理解切片的底层结构(底层数组、长度、容量)以及指针传递对切片头的影响。直接传切片本身是传值(复制 slice header),无法让调用方看到 append 或重分配后的变化;而传 *[]T 才能真正修改原始切片变量。
Go 的切片是引用类型,但它的 header(包含指向底层数组的指针、len、cap)是按值传递的。函数内对切片做 append、重新赋值等操作,只会影响副本的 header,不会影响调用方的变量。
当需要动态增删、扩容、整体替换结构体切片时,必须传入指向切片的指针。
func addUser(users *[]User, u User) {
*users = append(*users, u)
}
func main() {
var list []User
addUser(&list, User{Name: "Alice"})
fmt.Println(len(list)) // 输出 1
}
相比指针解引用,多数 Go 项目更倾向“函数返回新切片,由调用方显式接收”。它语义清晰、避免隐式副作用、利于并发安全,且编译器优化充分。
若目标是修改每个结构体的字段(而非增删切片元素),建议直接使用 []*User。这样每个元素是指向结构体的指针,修改字段无需拷贝整个结构体,也无需传指针切片。
r i := range users { ptrs = append(ptrs, &users[i]) }