实参与形参数

func printNumber(args ...int)
  • 形式参数:是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数。
  • 实际参数:在调用有参函数时,主调函数和被调函数之间有数据传递关系。在主调函数中调用一个函数时,函数名后面括号中的参数称为“实际参数”。
func main()  {
 var args int64= 1
 printNumber(args)  // args就是实际参数
}

func printNumber(args ...int64)  { //这里定义的args就是形式参数
 for _,arg := range args{
  fmt.Println(arg) 
 }
}

什么是值传递

什么是值传递,传递的是值,也就是说,函数传递的原来数据的拷贝,一个副本,比如当传递一个 int 类型的参数,传递的其实是这个参数的一个副本。 传递一个指针类型的参数,其实传递的就是这个指针类型的拷贝,而不是这个指针执行的值。

什么是引用传递

引用传递是指在函数调用过程中,是将实际参数的地址传递到函数中, 然后在函数中对参数进行修改,会影响到实际值。


golang是值传递

package gobase

import (
 "fmt"
 "testing"
)

func TestReference(t *testing.T) {
 var args int64 = 1
 modifiedNumber(args) // args就是实际参数
 fmt.Printf("实际参数的地址 %p\n", &args)
 fmt.Printf("改动后的值是  %d\n", args)
}

func modifiedNumber(args int64) { //这里定义的args就是形式参数
 fmt.Printf("形参地址 %p \n", &args)
 args = 10
}

运行结果:

=== RUN   TestReference
形参地址 0xc0000a01c8 
实际参数的地址 0xc0000a01c0
改动后的值是  1
--- PASS: TestReference (0.00s)
PASS

上面运行结果可以看出,go 是值传递, 但是不能确定 Go 是否只有值传递,也没有引用传递?

传递一个引用参数类型测试一下:

func TestReference2(t *testing.T)  {
 var args int64= 1
 addr := &args
 fmt.Printf("原始指针的内存地址是 %p\n", addr)
 fmt.Printf("指针变量addr存放的地址 %p\n", &addr)
 modifiedNumber2(addr) // args就是实际参数
 fmt.Printf("改动后的值是  %d\n",args)
}

func modifiedNumber2(addr *int64)  { //这里定义的args就是形式参数
 fmt.Printf("形参地址 %p \n",&addr)
 *addr = 10
}

运行结果

=== RUN   TestReference2
原始指针的内存地址是 0xc0001221d0
指针变量addr存放的地址 0xc00012c028
形参地址 0xc00012c030 
改动后的值是  10
--- PASS: TestReference2 (0.00s)
PASS

通过输出可以看到,这个是指针拷贝, 存放两个指针到地址是不一样的, 虽然指针的内容相同,但是两个是不一样的指针。


我们声明了一个变量 args , 其值为1, 内存存放地址为 0xc000b4008 , 通过这个地址可以找到变量 args, 这个地址是 args 的指针 addr, 指针adrr其实也是一个指针类型的变量。需要内存来存放它, 对应的内存地址是 0xc000ae18, 指针存放的内容是 0xc000b4008, 在我们传递指针变量 addr 给 modifedNumber 的时候,该指针变量是指针的一个拷贝, 新拷贝的指针变量存放地址是 0xc0000ae028 ,对应存放的内容还是 0xc000b4008, 这个指向了 args 变量的, 于是可以修改 0xc000b4008 指针对应的值,也就是修改了 args 对应的值。

欢迎关注公众号:程序员开发者社区