当前位置:首页 > Go > 正文

Go语言函数参数传递详解(值传递 vs 指针传递,新手也能轻松掌握)

在学习 Go语言参数传递 的过程中,很多初学者都会对“值传递”和“指针传递”感到困惑。这篇文章将用通俗易懂的方式,带你彻底搞懂 Go 语言中函数参数是如何传递的,无论你是编程小白还是刚接触 Go,都能轻松理解!

什么是参数传递?

当我们调用一个函数时,通常需要给它一些数据,这些数据就是“参数”。Go 语言在传递参数时有两种方式:值传递指针传递。它们的核心区别在于:函数内部是否能修改原始变量的值。

Go语言函数参数传递详解(值传递 vs 指针传递,新手也能轻松掌握) Go语言参数传递 值传递 指针传递 函数参数 第1张

1. 值传递(Pass by Value)

值传递 中,Go 会把实参的副本传给函数。也就是说,函数内部操作的是一个“拷贝”,不会影响原始变量。

来看一个例子:

package mainimport "fmt"func changeValue(x int) {    x = 100  // 修改的是 x 的副本    fmt.Println("函数内 x =", x)}func main() {    a := 10    fmt.Println("调用前 a =", a)    changeValue(a)    fmt.Println("调用后 a =", a)  // a 仍然是 10}

输出结果:

调用前 a = 10函数内 x = 100调用后 a = 10

可以看到,即使函数内部把 x 改成了 100,外部的 a 依然没变。这就是 值传递 的特点:安全、隔离,但无法修改原值。

2. 指针传递(Pass by Pointer)

如果你希望函数能修改原始变量,就需要使用 指针传递。指针保存的是变量的内存地址,通过地址可以直接修改原始数据。

看下面这个例子:

package mainimport "fmt"func changeValueByPointer(x *int) {    *x = 100  // 通过指针修改原始值    fmt.Println("函数内 *x =", *x)}func main() {    a := 10    fmt.Println("调用前 a =", a)    changeValueByPointer(&a)  // 传入 a 的地址    fmt.Println("调用后 a =", a)  // a 变成了 100}

输出结果:

调用前 a = 10函数内 *x = 100调用后 a = 100

这次,我们把 &a(a 的地址)传给函数,函数通过 *x 直接修改了 a 的值。这就是 指针传递 的威力!

3. 结构体的传递

结构体在 Go 中默认也是 值传递。这意味着整个结构体会被复制一份传入函数。

type Person struct {    Name string    Age  int}func updatePerson(p Person) {    p.Age = 30  // 修改的是副本}func main() {    tom := Person{"Tom", 25}    updatePerson(tom)    fmt.Println(tom.Age)  // 输出 25,未改变}

如果想修改原始结构体,必须传指针:

func updatePersonPtr(p *Person) {    p.Age = 30  // 修改原始结构体}// 调用时:updatePersonPtr(&tom)fmt.Println(tom.Age)  // 输出 30

4. 如何选择?

  • ✅ 如果只是读取数据,用 值传递 更安全。
  • ✅ 如果要修改原始变量,或者结构体很大(避免复制开销),用 指针传递
  • ✅ 切片(slice)、map、channel 本身就是引用类型,即使值传递也能修改内容(但不能替换整个变量)。

总结

掌握 Go语言参数传递 是写出高效、正确代码的基础。记住:

“值传递是拷贝,指针传递是共享。”

当你理解了这一点,就能灵活运用 值传递指针传递,写出更清晰、高效的 Go 程序!

希望这篇教程对你有帮助!别忘了实践一下代码,动手才是最好的学习方式 😊