golang中的影子变量

1. 示例

package main

//定义一个数据类型
type SomeReq struct {
	Data []struct {
		Name string `json:"name"`
		Age  int    `json:"age"`
	} `json:"data"`
}

//
type jsonUnmarshal struct {
	reqData SomeReq
}

//方法1  a 类型为jsonUnmarshal
func (j jsonUnmarshal) JsonUnmarshal_1(reqData string) {
	err := json.Unmarshal([]byte(reqData), &j.reqData)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(j.reqData.Data)
	}
}

//方法1  a 类型为*jsonUnmarshal
func (j *jsonUnmarshal) JsonUnmarshal_2(reqData string) {
	err := json.Unmarshal([]byte(reqData), &j.reqData)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(j.reqData)
	}
}

func main() {
	var data = `{"data":[{"name":"adada","age":1}]}`
	//声明变量a 为jsonUnmarshal类型
	var a jsonUnmarshal 
	a.JsonUnmarshal_1(data)
	fmt.Printf("[方法1执行后的j.reqData]:%v\n", a.reqData)
	a.JsonUnmarshal_2(data)
	fmt.Printf("[方法2执行后的j.reqData]:%v\n", a.reqData)
}

输出

[{adada 1}]
[方法1执行后的j.reqData]:{[]}
{[{adada 1}]}
[方法2执行后的j.reqData]:{[{adada 1}]}

2. 问题描述

明明是一样的操作,你会发现,最终打印出来的结果不一样。

3. 问题分析

问题在于声明函数时func (j 结构体类型)这部分造成的影响。

3.1 结构体类型为jsonUnmarshal

局部变量j是把变量a的值复制了一份,也就是传说中的值拷贝。这意味着你对j的操作只在函数内部生效,不会影响到a。如果你打印a的地址,会发现和a的地址和变量j的不一样。

3.2 结构体类型为*jsonUnmarshal

局部变量j是拿到了变量a的内存地址,操作j的也就是操作a

4. 开发时的技巧

常在河边走哪有不湿鞋,虽然道理懂了但总会有失手的时候。如果发现拿到的字段值不对时,就应该想到是这个问题。
此外,debug时看到这样的现象就需要引起注意。
在这里插入图片描述
你会发现j这个变量出现了两个。多出了一个j(shadowed),就是影子变量的意思。这个时候就应该意识到对j的操作只会在方法内部生效。
影子变量指的是代码执行过程中,出现了变量名称相同,但是内存地址不同的情况。
也就是同一个变量名被声明了多次,像这样
图片引用自https://blog.youkuaiyun.com/qq_38712932/article/details/126063841

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值