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中函数默认值使用注意点详解
Jun 01 Python
查看TensorFlow checkpoint文件中的变量名和对应值方法
Jun 14 Python
Python sorted函数详解(高级篇)
Sep 18 Python
Flask实现跨域请求的处理方法
Sep 27 Python
Python 判断图像是否读取成功的方法
Jan 26 Python
深入解析Python小白学习【操作列表】
Mar 23 Python
Python 类的私有属性和私有方法实例分析
Sep 29 Python
pycharm 中mark directory as exclude的用法详解
Feb 14 Python
pandas分批读取大数据集教程
Jun 06 Python
PyTorch预训练Bert模型的示例
Nov 17 Python
Prometheus开发中间件Exporter过程详解
Nov 30 Python
python实现图片九宫格分割的示例
Apr 25 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
DC这些乐高系列动画电影你看过几部?
2020/04/09 欧美动漫
教你如何使用php session
2013/10/28 PHP
PHP数据的提交与过滤基本操作实例详解
2016/11/11 PHP
PHP实现对数组分页处理实例详解
2017/02/07 PHP
thinkPHP框架可添加js事件的分页类customPage.class.php完整实例
2017/03/16 PHP
用示例说明filter()与find()的用法以及children()与find()的区别分析
2013/04/26 Javascript
jquery中通过父级查找进行定位示例
2013/06/28 Javascript
jquery 实现窗口的最大化不论什么情况
2013/09/03 Javascript
Knockout visible绑定使用方法
2013/11/15 Javascript
jQuery操作JSON的CRUD用法实例
2015/02/25 Javascript
JavaScript中Cookies的相关使用教程
2015/06/04 Javascript
js省市县三级联动效果实例
2020/04/15 Javascript
js实现可控制左右方向的无缝滚动效果
2016/05/29 Javascript
JS刷新父窗口的几种方式小结(推荐)
2016/11/09 Javascript
yarn的使用与升级Node.js的方法详解
2017/06/04 Javascript
jQuery常见面试题之DOM操作详析
2017/07/05 jQuery
jQuery实现点击DIV同时点击CheckBox,并为DIV上背景色的实例
2017/12/18 jQuery
vue-router配合ElementUI实现导航的实例
2018/02/11 Javascript
vue如何使用rem适配
2021/02/06 Vue.js
Python使用BeautifulSoup库解析HTML基本使用教程
2016/03/31 Python
查看django版本的方法分享
2018/05/14 Python
Python接口自动化判断元素原理解析
2020/02/24 Python
树莓派升级python的具体步骤
2020/07/05 Python
外企求职信范文分享
2013/12/31 职场文书
最新奶茶店创业计划书
2014/01/25 职场文书
教师节演讲稿
2014/05/06 职场文书
幼儿教师求职信
2014/05/24 职场文书
法律专业自荐信
2014/06/03 职场文书
安全施工责任书
2014/08/25 职场文书
学习考察心得体会
2014/09/04 职场文书
教师自我剖析材料(群众路线)
2014/09/29 职场文书
师德先进个人事迹材料
2014/12/19 职场文书
清明节网上祭英烈寄语2015
2015/03/04 职场文书
使用HTML+Css+transform实现3D导航栏的示例代码
2021/03/31 HTML / CSS
css position fixed 左右双定位的实现代码
2021/04/29 HTML / CSS
如何开启Apache,Nginx和IIS服务器的GZIP压缩功能
2022/04/29 Servers