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的垃圾回收机制
Dec 17 Python
Python 类的特殊成员解析
Jun 20 Python
python使用knn实现特征向量分类
Dec 26 Python
python xpath获取页面注释的方法
Jan 14 Python
Python3.5内置模块之random模块用法实例分析
Apr 26 Python
对pyqt5中QTabWidget的相关操作详解
Jun 21 Python
实例详解Python装饰器与闭包
Jul 29 Python
python并发编程多进程之守护进程原理解析
Aug 20 Python
Python如何使用BeautifulSoup爬取网页信息
Nov 26 Python
python使用SQLAlchemy操作MySQL
Jan 02 Python
Python合并pdf文件的工具
Jul 01 Python
python pandas 解析(读取、写入)CSV 文件的操作方法
Dec 24 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 无限级缓存的类的扩展
2009/03/16 PHP
php获取远程文件内容的函数
2015/11/02 PHP
php生成二维码图片方法汇总
2016/12/17 PHP
PHP中字符串长度的截取用法示例
2017/01/12 PHP
Javascript中的数学函数集合
2007/05/08 Javascript
javascript setTimeout和setInterval计时的区别详解
2013/06/21 Javascript
javascript算法题:求任意一个1-9位不重复的N位数在该组合中的大小排列序号
2015/04/01 Javascript
js控制元素显示在屏幕固定位置及监听屏幕高度变化的方法
2015/08/11 Javascript
第七章之菜单按钮图标组件
2016/04/25 Javascript
使用jQuery加载html页面到指定的div实现方法
2016/07/13 Javascript
js中获取jsp表单中radio类型的值简单实例
2016/08/15 Javascript
jQuery EasyUI Tab 选项卡问题小结
2016/08/16 Javascript
判断js的Array和Object的实现方法
2016/08/29 Javascript
angular route中使用resolve在uglify压缩后问题解决
2016/09/21 Javascript
bootstrap监听滚动实现头部跟随滚动
2016/11/08 Javascript
微信小程序-form表单提交代码实例
2019/04/29 Javascript
[01:20]DOTA2 齐天大圣至宝动态展示
2016/12/13 DOTA
Python 流程控制实例代码
2009/09/25 Python
python使用点操作符访问字典(dict)数据的方法
2015/03/16 Python
Python使用urllib2模块抓取HTML页面资源的实例分享
2016/05/03 Python
Python实现自动为照片添加日期并分类的方法
2017/09/30 Python
Python实现串口通信(pyserial)过程解析
2019/09/25 Python
使用python爬取抖音app视频的实例代码
2020/12/01 Python
使用phonegap播放音频的实现方法
2017/03/31 HTML / CSS
爱淘宝:淘宝网购物分享平台
2017/04/28 全球购物
BCBG官网:BCBGMAXAZRIA
2017/12/29 全球购物
《雨点》教学反思
2014/02/12 职场文书
《七颗钻石》教学反思
2014/02/28 职场文书
教师师德演讲稿
2014/05/06 职场文书
心理健康日活动总结
2014/05/08 职场文书
优秀会计求职信
2014/07/04 职场文书
2014年行政人事工作总结
2014/12/09 职场文书
2015年会计个人工作总结
2015/04/02 职场文书
电话营销开场白
2015/05/29 职场文书
初中数学教学随笔
2015/08/15 职场文书
go使用Gin框架利用阿里云实现短信验证码功能
2021/08/04 Golang