通八洲科技

如何在Golang中理解值类型和引用类型区别_函数传参示例

日期:2026-01-02 00:00 / 作者:P粉602998670
Go语言中所有参数均为值传递,但int等值类型复制全部内容,slice等引用类型仅复制header(含指针),故修改元素影响原变量;需改原始值必须传指针。

Go语言中没有传统意义上的“引用类型”,所有参数都是值传递,但不同数据类型的底层行为差异会让开发者产生“值类型”和“引用类型”的直观感受。关键在于:传递的是变量的副本,而这个副本的内容决定了它是“独立拷贝”还是“指向同一底层资源”的句柄。

哪些是常说的“值类型”

包括 intfloat64boolstringstructarray 等。它们在赋值或传参时,整个数据内容被完整复制一份。

哪些常被当作“引用类型”使用

包括 slicemapchannelfuncinterface{}。它们本质是**头信息结构体(header)**,内部包含指针、长度、容量等字段,传参时只复制这个 header,而非底层数据。

指针类型:真正可控的“引用”方式

如果你需要在函数内修改原始变量的值(比如改变 int 变量内容、替换 struct 字段、或让 slice 指向新数组),必须显式传入指针。

立即学习“go语言免费学习笔记(深入)”;

一个对比示例

以下代码清晰展示差异:

func modifyInt(x int) { x = 999 }
func modifySlice(s []int) { s[0] = 999; s = append(s, 123) }
func modifySlicePtr(s *[]int) { *s = append(*s, 456) }

func main() {
    a := 10
    modifyInt(a)
    fmt.Println(a) // 输出 10 —— 值类型,未变

    s := []int{1, 2, 3}
    modifySlice(s)
    fmt.Println(s) // 输出 [999 2 3] —— 元素被改,但 append 没影响原 s

    modifySlicePtr(&s)
    fmt.Println(s) // 输出 [999 2 3 456] —— 通过指针成功追加
}