
我们的业务代码中习惯使用 Map
维护一些 LocalCache
,前两天发现自己维护的一个 LocalCache
数据有些不对:Cache 的 Key
为某个对象的ID,值为这个ID对应的 PO
(即数据库中的对象),调试时发现所有的 Key
对应的值都是一样的,这是因为自己对一些细节没有关注到,还把 Java 那套东西搬来用导致的问题。
为了简化,我就不把业务代码搬上来了,写个简单的示例:
1 | package main |
上边代码输出如下:
1 | {"1":{"ID":3,"Name":"王五","Age":20},"2":{"ID":3,"Name":"王五","Age":20},"3":{"ID":3,"Name":"王五","Age":20}} |
可以看到所有的 value
是同一个 Student
,为什么会出现这样的问题呢?因为 students
存储的是 Student
的值,在给 for
循环中的 student
赋值时,是复制了一个新的值给它,而 for
循环中的 student
变量所指向的地址是不变的。
可以打印 student 的地址看一下:
1 | for _, student := range students { |
输出为:
1 | 0xc0000a6040 |
这种情况下我们应该用 students
中索引对应数据的指针,上边 for 循环修改如下:
1 | for i, student := range students { |
输出为:
1 | 0xc0000b8000 |
上边的情况给 student
赋值也是有问题的:
1 | for _, student := range students { |
输出:
1 | [{"ID":1,"Name":"张三","Age":18},{"ID":2,"Name":"李四","Age":19},{"ID":3,"Name":"王五","Age":20}] |
Java 写习惯了就以为迭代时的 student
指向的是 students
中的地址。