【发布时间】:2018-04-28 09:46:47
【问题描述】:
此代码提供了 AFAIK 正确的 JSON 输出 [{},{}],但每一行都被追加并替换所有先前的行,因此结果仅显示最后一行的副本。
var rows *sql.Rows
rows, err = db.Query(query)
cols, _ := rows.Columns()
colnames, _ := rows.Columns()
vals := make([]interface{}, len(cols))
for i, _ := range cols {
vals[i] = &cols[i]
}
m := make(map[string]interface{})
for i, val := range vals {
m[colnames[i]] = val
}
list := make([]map[string]interface{}, 0)
for rows.Next() {
err = rows.Scan(vals...)
list = append(list, m)
}
json, _ := json.Marshal(list)
fmt.Fprintf(w,"%s\n", json)
这是在幕后循环遍历行的情况:
循环 1:{“ID”:“1”,“NAME”:“约翰 }
循环 2:{“ID”:“2”,“NAME”:“Jane Doe”}{“ID”:“2”,“NAME”:“Jane Doe”}
循环 3:{“ID”:“3”,“NAME”:“唐老鸭”}{“ID”:“3”,“NAME”:“唐老鸭”}{“ID”:“3” ,“名字”:“唐老鸭”}
rows.Scan 获取正确的值,但它附加并替换所有以前的值。
最终的输出是这样的
[{“ID”:“3”,“NAME”:“唐老鸭”},{“ID”:“3”,“NAME”:“唐老鸭”},{“ID”:“3” ,“名称”: “唐老鸭”}]
但应该是这样的:
[{“ID”:“1”,“NAME”:“John Doe”},{“ID”:“2”,“NAME”:“Jane Doe”},{“ID”:“3” ,“名称”: “唐老鸭”}]
我做错了什么?
您可以对此投反对票,但请解释原因。我还是 Golang 的新手,想学习。
【问题讨论】:
-
您在不修改 m 的情况下一遍又一遍地将 m 添加到列表中。为什么你期望切片元素之后会有所不同?
-
哦,我现在明白了。您似乎认为 m 以某种方式被复制。那是a)不正确,b)不会改变任何东西,因为地图存储了指针。所以复制地图会复制指针,但它们仍将指向相同的值。但是 Scan 改变了指向的值,而不是指针;地址不变。长话短说,
make每行都有一张新地图。
标签: go