Go函数返回值是否影响原数据取决于类型:值类型(如int、struct)返回独立拷贝,修改不影响原变量;引用类型(如slice、map)返回描述符拷贝,元素修改可能影响底层数组,但变量本身修改不共享。
在 Go 语言中,函数返回值是否影响原数据,关键取决于该值是值类型还是引用类型。对于值类型(如 int、string、struct、[3]int 等),函数返回的是原值的独立拷贝,对返回值的修改绝不会影响调用时传入的原始变量。
Go 中所有值类型在赋值、传参、返回时都会发生“按值传递”,也就是复制一份全新副本到新内存位置。这意味着:
假设定义了一个简单结构体:
type Point struct { X, Y int }
写一个返回 Point 的函数:
调用它:
p1 := getOrigin()此时 p1.X 仍是 0,p2.X 是 99。因为 p1 和 p2 是两个独立的 struct 实例,各自拥有自己的内存空间。
虽然 slice 看似像数组,但它本质是包含指针、长度、容量的结构体(即值类型)。所以 func getSlice() []int 返回的仍是值拷贝——但这个“值”里存着指向底层数组的指针。因此:
s[0] = 100)可能影响原底层数组s = append(s, 1))不会改变调用方的 slice 变量,因为 header 被拷贝了这容易造成误解,但根源仍是:返回的仍是值(header 结构体),只是这个值“携带”了共享资源的访问路径。
判断标准很直接:
int、float64、其他 struct 等)→ 全局拷贝,绝对隔离[]T、map[K]V、*T、func()、channel → 拷贝的是“描述信息”,底层数据仍可能共享fmt.Printf("%p", &v) 打印地址,或用 unsafe.Sizeof(v) 看实际大小,能快速验证是否为纯值布局