Go中的值类型包括基本类型、数组、结构体和指针,作为函数参数时会被复制,函数内操作的是副本,不影响原值;例如结构体传参修改后原值不变;若需修改原值或提升性能,应使用指针传参,因指针复制的是地址,可指向并修改原始对象;小对象值传递开销小,大对象建议用指针避免性能损耗;字符串底层为只读,复制开销较小。

在 Go 语言中,值类型作为函数参数时会被复制。这意味着传递给函数的是原始数据的一个副本,而不是原始数据本身。
什么是值类型
Go 中的值类型包括:
- 基本类型(如 int、float64、bool、string)
- 数组(array)
- 结构体(struct)
- 指针虽然也是值类型,但它存储的是地址,复制的是地址值
当这些类型的变量作为函数参数传入时,Go 会创建该值的一个副本,函数内部操作的是这个副本,不会影响原值。
值传递的实际影响
以结构体为例:
立即学习“go语言免费学习笔记(深入)”;
type Person struct {
Name string
Age int
}
func modify(p Person) {
p.Age = 30
fmt.Println("函数内:", p.Age) // 输出 30
}
func main() {
person := Person{Name: "Alice", Age: 25}
modify(person)
fmt.Println("函数外:", person.Age) // 仍为 25
}
可以看到,函数内对结构体的修改不影响原始变量,因为传入的是副本。
如何避免复制或修改原值
如果希望函数能修改原始值,或者想避免大对象复制带来的性能开销,应该使用指针:
func modifyPointer(p *Person) {
p.Age = 30
}
func main() {
person := Person{Name: "Alice", Age: 25}
modifyPointer(&person)
fmt.Println(person.Age) // 输出 30
}
此时传递的是指向原对象的指针,虽然指针本身是值传递(地址被复制),但它指向的是原始结构体,因此可以修改原值。
性能考虑
对于小型值(如 int、bool),复制成本很低,无需担心。但对于大型结构体或数组,频繁复制会影响性能。这种情况下推荐传指针。
注意:字符串虽然是值类型,但底层是只读的,传递时复制的是包含指针和长度的小结构体,开销较小。
基本上就这些。Go 的值传递机制简单直接,理解复制行为有助于写出更高效、正确的代码。










