小弟今天开发项目,发现一个奇怪问题 首先小弟的信息是从数据库中取出来的,取出来预备组成[]struct 返回给前端,进行任务展示,这是前提 数据库中有任务三条, 任务 1:
{[{false 1KB-20KB}] [] []}} b5a33d9d-6512-11ea-8001-000000000000 {2 0 }
任务 2:
{[{true 1GB-1TB}] [] []}} fee23a86-6506-11ea-8001-000000000000 {2 0 }}
任务 3:
{[{false 1KB-2KB}] [] []}} 9b995076-6514-11ea-8002-000000000000 {2 0 }
我利用了 append,组合成一个[]struct,可是输出之后发现
[{{[] [{false 1KB-2KB}] [] []}} 9b995076-6514-11ea-8002-000000000000 {2 0 }},
{{[]{false 1KB-2KB}] [] []}} fee23a86-6506-11ea-8001-000000000000 {2 0 }},
{{[{false 1KB-2KB}] [] []}} b5a33d9d-6512-11ea-8001-000000000000 {2 0 }}]
所有的 false 都被固定成 1kb-2kb 了,小弟写过 python,怀疑是 deepcopy 或者是 copy 的问题,但是 golang 这里实在不熟,请各位大神给小弟一点点灵感吧,谢谢!
附上代码
var sync infimanage.Sync
var synclists []infimanage.Sync
// fmt.Println(msg)
etcd, err := infidb.New()
if err != nil {
fmt.Println(err)
}
syncslist, err := etcd.GetPrefixAllValue("syncwork/")
if err != nil {
fmt.Println(err)
}
for _, syncs := range syncslist {
json.Unmarshal([]byte(syncs), &sync)
fmt.Println(sync)
// 这里打印输出都是正常的
fmt.Println("xxxxxxxxxxxxxxxxxx")
synclists = append(synclists, sync)
}
// 这里就不正常了
fmt.Println(synclists)
1
vus520 2020-03-15 20:38:59 +08:00
看不懂,是我的话就提前定义好 struct,取出来以后全还原到 struct 对象,再处理
|
2
whoami9894 2020-03-15 20:39:30 +08:00 via Android
全部都 unmarshal 到同一块内存了,你应该每轮迭代定义个新 sync
|
3
PEIENYKYK OP @whoami9894 对,您的点拨很到位,谢谢谢谢!感恩
|
4
newmiao 2020-03-15 20:50:01 +08:00
好像知乎上看到你的问题,回答了你,怀疑是 for-range 用了指针,参考: https://mp.weixin.qq.com/s/klJBAi5LvdJOGvma2Ir0OA
|
5
bintianbaihua 2020-03-15 21:09:59 +08:00
for-range 的经典坑。
|
6
whoami9894 2020-03-15 22:25:03 +08:00
@whoami9894 #2
又看了一下,还有点问题 如果你那个`infimanage.Sync`是个 interface 并且实际类型是个 pointer 的话才会出现我#2 说的问题,不过看你最后生成的数据里只有`{false 1KB-2KB}`相同,后面的 uuid 是不同的,那么就排除我#2 说的情况。猜测是你后两次迭代的 JSON 数据中`{false 1KB-2KB}`字段有误(比如字段名出错),导致只 unmarshal 了后面的正常数据到你复用的 sync 里,然后把 sync 的拷贝 append 而且你粘贴的输出明显有问题: `{[] [{false 1KB-2KB}] [] []}}` `{[]{false 1KB-2KB}] [] []}}` `{[{false 1KB-2KB}] [] []}}` 建议按上面几点自己排查一下 |
7
rrfeng 2020-03-16 10:47:41 +08:00
把第一行 var sync infimanage.Sync 挪到 for 循环里面。
|