【GO语言学习笔记】关于defer的一些问题解释

前言

  • 问题来源指路
  • 本文内容主要解释向defer语句中传指针(引用类型),然后修改指针指向的变量的值,这种操作是否会导致defer语句中输出的值发生改变。
  • 假设n := 1 ptr := &n solve(ptr),你觉得下面两个例子的输出分别是什么呢?
    例1
    func solve(n *int) {
    	defer fmt.Println(*n)
    	*n++
    }
    
    例2
    func solve(n *int) {
    	defer solve1(n)
    	*n++
    }
    func solve1(n *int) {
    	fmt.Println(*n)
    }}
    

输出结果以及解释

输出结果

输出
例11
例22

解释

  • 只有defer语句后面的函数及其参数会被压入一个全新的栈中,即只能维持defer语句后面的函数及参数的值的不变
    • 对于样例1来说,输出函数和指针n指向的值(*代表解引用)被压入栈中,此时在外部修改指针n指向的值并不会影响输出函数的结果,因为输出函数的参数是从栈中取出的,而非从指针n指向的地址取出的。
栈帧
fmt.Println()
参数1(*n)
  • 于样例2来说,输出函数和指针n被压入栈中,此时在外部修改指针n指向的值会影响输出函数的结果。因为从栈中取出的solve1的参数是一个指针(地址是指针的值,defer维持了指针指向的地址不变),其指向的值发生了变化,因此会影响输出结果。
栈帧
solve1
参数1(n)

结论

  1. defer语句会开辟一个全新的栈帧,维持后面的函数及参数的值的不变
  2. 造成上述误导的根源在于指针的值是一个地址,defer只会维持地址不变,而不会维持地址指向的值不变。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值