对于一门语言,在函数传参时,存在两种方式,一种是值传递,一种是引用传递,那么go语言是怎么进行参数传递的
值传递是传递的变量的副本,引用传递指的是传递该变量的地址,在值传递过程中,函数对函数形参数的修改,不会导致实参的修改,而引用传参,对形参的修改,会导致该实参的修改,这是过去我们在其它语言中的一些认知,那么go语言会颠覆我们过去的认知,使用了一种新的方式.
- demo1
package main
import (
"fmt"
)
func main() {
a := 10
fmt.Println("实参的地址",&a)
update(a)
fmt.Println(a)
}
func update(b int) {
b = 1
fmt.Println("形参的地址",&b)
}
// 运行结果
实参的地址 0x10414020
形参的地址 0x10414024
10
由该demo,我们可以得出,在值传递时,形参是实参的一个copy
- demo2
package main
import (
"fmt"
)
func main() {
a := 10
p := &a
fmt.Println("指针的地址",&p)
fmt.Println("实参的地址",&a)
update(p)
fmt.Println(a)
}
func update(b *int) {
*b = 1
fmt.Println("形参的指针地址",&b)
fmt.Println("形参的地址",b)
}
// 运行结果
指针的地址 0x1040c128
实参的地址 0x10414020
形参的指针地址 0x1040c138
形参的地址 0x10414020
1
发现在指针传递时,实参和形参的指针地址不一值,但其指向地址是一样的,由此可以得出,在指针传递时,go语言,传递的是指针的copy,是一种值传递的方式
- demo3
再来看一个复杂的,结构体
package main
import (
"fmt"
)
type Person struct {
Name string
}
func main() {
p := Person{"zhang san"}
fmt.Printf("实参的地址:%p\n", &p)
update(p)
fmt.Println(p)
}
func update(p Person) {
p.Name = "li si"
fmt.Printf("形参的地址:%p\n", &p)
}
// 输出结果
实参的地址:0x1040c128
形参的地址:0x1040c138
{zhang san}
- demo4
指针传递
package main
import (
"fmt"
)
type Person struct {
Name string
}
func main() {
p := Person{"zhang san"}
pr := &p
fmt.Printf("实参的指针地址:%p\n", &pr)
fmt.Printf("实参的地址:%p\n", &p)
update(pr)
fmt.Println(p)
}
func update(p *Person) {
p.Name = "li si"
fmt.Printf("形参的指针地址:%p\n", &p)
fmt.Printf("形参的地址:%p\n", p)
}
// 运行结果
实参的指针地址:0x1040c130
实参的地址:0x1040c128
形参的指针地址:0x1040c140
形参的地址:0x1040c128
{li si}
由demo3和demo4的对比,分析可以得到,在值传递时,传递的是值的实参的副本,指针传递时,传递的是指针的副本,其都指向实参的地址
通过以上实验,可以得出,无论是值传递和指针传递,都传递的是对应的一个副本.在go语言中,只有一个值传递.
- demo5
package main
import (
"fmt"
)
type Person struct {
Name string
}
func main() {
persons:=make(map[string]int)
persons["张三"]=19
//mp:=&persons
fmt.Printf("原始map的内存地址是:%p\n",&persons)
update(persons)
fmt.Println("map值被修改了,新值为:",persons)
}
func update(p map[string]int) {
fmt.Printf("函数里接收到map的内存地址是:%p\n",&p)
p["张三"]=20
}
// 运行结果
原始map的内存地址是:0x1040c128
函数里接收到map的内存地址是:0x1040c138
map值被修改了,新值为: map[张三:20]
该demo运行结果和我们前面的推论结果不一致,在代码中有一个特殊的make,因此我们有理由怀疑,make得到的结果是一个指针类型,这样才符合我们前边的推论.
有疑问加站长微信联系(非本文作者)