go和python变量赋值遇到的一个问题


Posted in Python onAugust 31, 2017

平时写得多的是python,最近看了一点go,今天碰到了一个问题,和大家分享一下

package main

import "fmt"

type student struct {
  Name string
  Age int
}

func pase_student() {
  m := make(map[string]*student)
  stus := []student{
    {Name: "zhou", Age: 24},
    {Name: "li", Age: 23},
    {Name: "wang", Age: 22},
  }
  for _, stu := range stus {
    m[stu.Name] = &stu
  }
  fmt.Println(m["zhou"].Name)
}

func main() {
  pase_student()
}

代码很简单,大家可以思考一下会打印出什么。

time.sleep(60)  # 思考

结果是 wang !,惊喜不惊喜!遍历赋值啊同学们,这么简单的操作都能出幺蛾子,WTF!

为什么是 wang 呢?
你tm给我
解释解释
什么是惊喜

for循环的时候,变量stu的指针是不变的,每次循环仅仅是对student结构体的 值 拷贝,上面的for循环和下面是一样的:

var stu student 
for _, stu = range stus {
 m[stu.Name] = &stu
}

所以 &stu 自始至终都是一个地址,变化的是这个地址上存储的值。 &stu 最终存储的值是 student{Name: "wang", Age: 22} 结构体,所以拿出来的是 wang 。

可以将 m 打出来看一下:

map[zhou:0xc42000a260 li:0xc42000a260 wang:0xc42000a260]

验证了我们上面的想法,大家的value都是同一个地址。

看到这里,如果是一个日常写c,c++等强类型语言的同学可能会说,神经病啊!这有什么好说的!不就是这样的吗!请原谅我,我日常写python的 [捂脸]。

从上面的例子可以看出来,在go中,变量名是 存储地址的名字 。它在编译时绑定已经完成,运行时是不可以改变的,你只能改变地址中存储的值。

而在python中,变量是对象的名字,运行时变量可以绑定到任意的对象上。如下所示:

In [4]: a = 123456

In [5]: id(a)
Out[5]: 4426596208

In [6]: a = 1234567

In [7]: id(a)
Out[7]: 4426592592

注意:由于python对int类型实现了 小整数对象池 ,不要用 0-255 的整数做实验,不然你得到id会是一样的。

也就是说,当你循环一个list的时候,每次得到的是不同对象,变量指向了不同的地址:

In [9]: for i in [2222, 2223, 2224]:
  ...:   print(id(i))
  ...:
4426596208
4426592336
4426596080

上面这段代码,python为我们创建了3个 PyIntObject , i 只是他们的名字。而在go中,可以认为只有一个object,值变化了3次。

python中说的 赋值就是建立一个对象的引用 ,是实话。

Python 相关文章推荐
python re正则表达式模块(Regular Expression)
Jul 16 Python
仅用500行Python代码实现一个英文解析器的教程
Apr 02 Python
Python获取邮件地址的方法
Jul 10 Python
基于Pandas读取csv文件Error的总结
Jun 15 Python
linux中如何使用python3获取ip地址
Jul 15 Python
pip安装python库的方法总结
Aug 02 Python
Python数据可视化:幂律分布实例详解
Dec 07 Python
python实现拼图小游戏
Feb 22 Python
Python grequests模块使用场景及代码实例
Aug 10 Python
python判断变量是否为列表的方法
Sep 17 Python
python如何写个俄罗斯方块
Nov 06 Python
详解Open Folder as PyCharm Project怎么添加的方法
Dec 29 Python
理解Python中的绝对路径和相对路径
Aug 30 #Python
python 递归遍历文件夹,并打印满足条件的文件路径实例
Aug 30 #Python
python递归打印某个目录的内容(实例讲解)
Aug 30 #Python
python-opencv在有噪音的情况下提取图像的轮廓实例
Aug 30 #Python
关于python的list相关知识(推荐)
Aug 30 #Python
Python编程实现正则删除命令功能
Aug 30 #Python
Python删除Java源文件中全部注释的实现方法
Aug 30 #Python
You might like
PHP学习之数组的定义和填充
2011/04/17 PHP
Swoole实现异步投递task任务案例详解
2019/04/02 PHP
用JavaScript脚本实现Web页面信息交互
2006/10/11 Javascript
面向切面编程(AOP)的理解
2015/05/01 Javascript
JavaScript代码性能优化总结篇
2016/05/15 Javascript
jQuery使用each方法与for语句遍历数组示例
2016/06/16 Javascript
利用JS实现点击按钮后图片自动切换的简单方法
2016/10/24 Javascript
Vue.js双向绑定实现原理详解
2016/12/22 Javascript
微信小程序 详解下拉加载与上拉刷新实现方法
2017/01/13 Javascript
angular.js指令中的controller、compile与link函数的不同之处
2017/05/10 Javascript
获取url中用&隔开的参数实例(分享)
2017/05/28 Javascript
详解Vue 多级组件透传新方法provide/inject
2018/05/09 Javascript
微信小程序—setTimeOut定时器的问题及解决
2019/07/26 Javascript
js刷新页面location.reload()用法详解
2019/12/09 Javascript
如何使用jQuery操作Cookies方法解析
2020/09/08 jQuery
Python字符串和文件操作常用函数分析
2015/04/08 Python
Python中的高级函数map/reduce使用实例
2015/04/13 Python
django+xadmin+djcelery实现后台管理定时任务
2018/08/14 Python
Python+PyQt5实现美剧爬虫可视工具的方法
2019/04/25 Python
keras绘制acc和loss曲线图实例
2020/06/15 Python
.img/.hdr格式转.nii格式的操作
2020/07/01 Python
关于PySnooper 永远不要使用print进行调试的问题
2021/03/04 Python
马来西亚时装购物网站:ZALORA马来西亚
2017/03/14 全球购物
美国著名手表网站:Timepiece
2017/11/15 全球购物
Whistles官网:英国女装品牌
2020/08/14 全球购物
2014年中秋节活动总结
2014/08/29 职场文书
在教室放鞭炮的检讨书
2014/09/28 职场文书
机械专业毕业生自我鉴定2014
2014/10/04 职场文书
思想政治表现评语
2015/01/04 职场文书
员工升职自荐信
2015/03/27 职场文书
博士论文答辩开场白
2015/06/01 职场文书
2016中考冲刺决心书
2015/09/22 职场文书
JavaScript如何优化逻辑判断代码详解
2021/06/08 Javascript
Python中的xlrd模块使用整理
2021/06/15 Python
Python 类,对象,数据分类,函数参数传递详解
2021/09/25 Python
实战 快速定位MySQL的慢SQL
2022/03/22 MySQL