Go语言学习-- No.10 函数---函数参数传递的本质

值传递

值传递: 将变量的一个副本传递给函数,函数中不管如何操作该变量副本,都不会改变原变量的值。

引用传递

引用传递:将变量的内存地址传递给函数,函数中操作变量时会找到保存在该地址的变量,对其进行操作,会改变原变量的值

Go语言参数的传递形式总是值传递

值类型变量

对于int、string和bool等值类型变量,传递的是原变量的副本,对副本的操作不会影响原变量。
举例:

package main

import "fmt"

func passByValue(numPara int) {
	fmt.Println("passByValue函数中变量numPara地址为: ", &numPara)  // &参数= 参数的地址
	numPara = 100
	fmt.Println("对值变量在自定义的函数内部进行修改后为 : ", numPara)
}
func main() {
	num := 1
	fmt.Println("main函数中的num地址为: ", &num)
	passByValue(num)
	fmt.Println("main函数中的num变量的值: ", num)
}

// main函数中的num地址为:  0xc000014098
// passByValue函数中变量numPara地址为:  0xc0000140c0
// 对值变量在自定义的函数内部进行修改后为 :  100
// main函数中的num变量的值:  1

结论:

  • main函数中定义的 num 地址 ,和 自定义函数中的 参数num 地址不一样,说明自定义函数中的num为main函数num的副本

  • 对自定义函数num的修改,即为在函数内部对局部变量进行修改,无法影响mian函数的num 。因此局部参量(副本) 的改变无法影响主变量的参数(main函数中的num)

引用类型变量

对于指针、切片、map和channel(通道)引用类型变量,传递的是原变量指针的一份副本,该副本指向了原变量地址,因此对该副本的操作会影响原变量,从而达到了其他编程语言中类似于引用传递的效果。

举例1:

package main

import "fmt"

func passByReference(numPara *int) {
	fmt.Println("passByReference函数中指针变量numPara(引用型变量)内容为: ", numPara)
	fmt.Println("passByReference函数中指针变量numPara(引用型变量)地址为: ", &numPara)

	fmt.Println("对指针变量进行修改 ..... ")
	*numPara = 100
	fmt.Println("对指针变量(引用型变量)在自定义的函数内部进行修改后内容为 : ", numPara)
	fmt.Println("对指针变量(引用型变量)在自定义的函数内部进行修改后地址为 : ", &numPara)
}
func main() {
	num := 1
	fmt.Println("main函数中的num地址为: ", &num)
	passByReference(&num)
	fmt.Println("main函数中的num变量的值: ", &num)
}

// main函数中的num地址为:  0xc0000aa058
// passByReference函数中指针变量numPara(引用型变量)内容为:  0xc0000aa058
// passByReference函数中指针变量numPara(引用型变量)地址为:  0xc0000ce020
// 对指针变量进行修改 .....
// 对指针变量(引用型变量)在自定义的函数内部进行修改后内容为 :  0xc0000aa058
// 对指针变量(引用型变量)在自定义的函数内部进行修改后地址为 :  0xc0000ce020
// main函数中的num变量的值:  0xc0000aa058

可以看出:

  • 在自定义函数中对引用型变量(也就是是指针)进行修改会影响到main() 函数中定义的引用型变量(此处为指针)

举例2 :

使用map变量传递的是原变量的指针。

package main

import "fmt"

func passByReference(mapNumReference map[int]int) {
	fmt.Println("passByReference函数中变量mapNumReference地址为: ", mapNumReference)
	fmt.Println("passByReference函数中变量mapNumReference所属指针地址为: ", &mapNumReference)
	mapNumReference[1] = 100
}

func main() {
	mapNum := map[int]int{1: 10}
	fmt.Println("main函数中的变量mapNum为: ", mapNum)
	fmt.Println("main函数中的变量mapNum所属的指针地址为: ", &mapNum)
	fmt.Println("mapNum变量值为: ", mapNum)
	passByReference(mapNum)
	fmt.Println("main函数中的变量mapNum为: ", mapNum)
}

// main函数中的变量mapNum为:  map[1:10]
// main函数中的变量mapNum所属的指针地址为:  &map[1:10]
// mapNum变量值为:  map[1:10]
// passByReference函数中变量mapNumReference地址为:  map[1:10]
// passByReference函数中变量mapNumReference所属指针地址为:  &map[1:10]
// main函数中的变量mapNum为:  map[1:100]

通过map类型变量参数传递的例子我们可以发现,函数进行值传递后拷贝的是map类型变量指针,但拷贝后的指针地址指向的还是map的地址,从而导致在函数passByReference中对map的操作会影响原变量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值