Go 有引用传递么?

简介: Go 有引用传递么?

实参与形参数


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 类型的参数,传递的其实是这个参数的一个副本。传递一个指针类型的参数,其实传递的就是这个指针类型的拷贝,而不是这个指针执行的值。

image.png

什么是引用传递

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

image.png

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

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

image.png

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

相关文章
|
5月前
|
Go
go值传递和引用传递
go值传递和引用传递
【Go 进阶】Go 语言到底是值传递,还是引用传递?(四)
【Go 进阶】Go 语言到底是值传递,还是引用传递?(四)
Go中都是值传递,切记! 你所了解的引用传递等知识经验从今天开始彻底抛弃!
Go中都是值传递,切记! 你所了解的引用传递等知识经验从今天开始彻底抛弃!
【Go 进阶】Go 语言到底是值传递,还是引用传递?(三)
【Go 进阶】Go 语言到底是值传递,还是引用传递?(三)
【Go 进阶】Go 语言到底是值传递,还是引用传递?(二)
【Go 进阶】Go 语言到底是值传递,还是引用传递?(二)
|
存储 Java 程序员
【Go 进阶】Go 语言到底是值传递,还是引用传递?(一)
【Go 进阶】Go 语言到底是值传递,还是引用传递?(一)
|
Go Python
清源正本,鉴往知来,Go lang1.18入门精炼教程,由白丁入鸿儒,Golang中引用类型是否进行引用传递EP18
开篇明义,Go lang中从来就不存在所谓的“引用传递”,从来就只有一种变量传递方式,那就是值传递。因为引用传递的前提是存在“引用变量”,但是Go lang中从来就没有出现过所谓的“引用变量”,所以也就不可能存在引用传递这种变量传递的方式。
清源正本,鉴往知来,Go lang1.18入门精炼教程,由白丁入鸿儒,Golang中引用类型是否进行引用传递EP18
|
9天前
|
存储 JSON 监控
Viper,一个Go语言配置管理神器!
Viper 是一个功能强大的 Go 语言配置管理库,支持从多种来源读取配置,包括文件、环境变量、远程配置中心等。本文详细介绍了 Viper 的核心特性和使用方法,包括从本地 YAML 文件和 Consul 远程配置中心读取配置的示例。Viper 的多来源配置、动态配置和轻松集成特性使其成为管理复杂应用配置的理想选择。
29 2
|
7天前
|
Go 索引
go语言中的循环语句
【11月更文挑战第4天】
18 2
|
7天前
|
Go C++
go语言中的条件语句
【11月更文挑战第4天】
20 2