对于一门语言,在函数传参时,存在两种方式,一种是值传递,一种是引用传递,那么go语言是怎么进行参数传递的
值传递是传递的变量的副本,引用传递指的是传递该变量的地址,在值传递过程中,函数对函数形参数的修改,不会导致实参的修改,而引用传参,对形参的修改,会导致该实参的修改,这是过去我们在其它语言中的一些认知,那么go语言会颠覆我们过去的认知,使用了一种新的方式.
demo1
packagemain
import(
"fmt"
)
funcmain(){
a:=10
fmt.Println("实参的地址",&a)
update(a)
fmt.Println(a)
}
funcupdate(bint){
b=1
fmt.Println("形参的地址",&b)
}
//运行结果
实参的地址0x10414020
形参的地址0x10414024
10
由该demo,我们可以得出,在值传递时,形参是实参的一个copy
demo2
packagemain
import(
"fmt"
)
funcmain(){
a:=10
p:=&a
fmt.Println("指针的地址",&p)
fmt.Println("实参的地址",&a)
update(p)
fmt.Println(a)
}
funcupdate(b*int){
*b=1
fmt.Println("形参的指针地址",&b)
fmt.Println("形参的地址",b)
}
//运行结果
指针的地址0x1040c128
实参的地址0x10414020
形参的指针地址0x1040c138
形参的地址0x10414020
1
发现在指针传递时,实参和形参的指针地址不一值,但其指向地址是一样的,由此可以得出,在指针传递时,go语言,传递的是指针的copy,是一种值传递的方式
demo3
再来看一个复杂的,结构体
packagemain
import(
"fmt"
)
typePersonstruct{
Namestring
}
funcmain(){
p:=Person{"zhangsan"}
fmt.Printf("实参的地址:%p\n",&p)
update(p)
fmt.Println(p)
}
funcupdate(pPerson){
p.Name="lisi"
fmt.Printf("形参的地址:%p\n",&p)
}
//输出结果
实参的地址:0x1040c128
形参的地址:0x1040c138
{zhangsan}
demo4
指针传递
packagemain
import(
"fmt"
)
typePersonstruct{
Namestring
}
funcmain(){
p:=Person{"zhangsan"}
pr:=&p
fmt.Printf("实参的指针地址:%p\n",&pr)
fmt.Printf("实参的地址:%p\n",&p)
update(pr)
fmt.Println(p)
}
funcupdate(p*Person){
p.Name="lisi"
fmt.Printf("形参的指针地址:%p\n",&p)
fmt.Printf("形参的地址:%p\n",p)
}
//运行结果
实参的指针地址:0x1040c130
实参的地址:0x1040c128
形参的指针地址:0x1040c140
形参的地址:0x1040c128
{lisi}
由demo3和demo4的对比,分析可以得到,在值传递时,传递的是值的实参的副本,指针传递时,传递的是指针的副本,其都指向实参的地址
通过以上实验,可以得出,无论是值传递和指针传递,都传递的是对应的一个副本.在go语言中,只有一个值传递.
demo5
packagemain
import(
"fmt"
)
typePersonstruct{
Namestring
}
文中图片素材来源网络,如有侵权请联系删除