我从数据库查询并尝试插入切片时遇到问题(包含一些map [string] interface {}) 即使我已经使用make来创建一个新的内存块,切片似乎总是映射到同一个内存块。
type DBResult []map[string]interface{}
func ResultRows(rows *sql.Rows, limit int) (DBResult, error) {
cols, err := rows.Columns()
if err != nil {
return nil, err
}
vals := make([]sql.RawBytes, len(cols))
scanArgs := make([]interface{}, len(vals))
for i := range vals {
scanArgs[i] = &vals[i]
}
if limit > QUERY_HARD_LIMIT {
limit = QUERY_HARD_LIMIT
}
res := make(DBResult, 0, limit)
for rows.Next() {
err = rows.Scan(scanArgs...)
m := make(map[string]interface{})
for i := range vals {
m[cols[i]] = vals[i]
}
/* Append m to res */
res = append(res, m)
/* The value of m has been changed */
fmt.Printf("lib: m:\n\n%s\n\n", m)
/* When printing res, always mapping to the same memory block */
fmt.Printf("lib: res:\n\n%s\n\n", res)
}
return res, err
}
以下是结果,你可以发现res的内容是相同的
m = map [评论:first_comment id:0]
res = [map [id:0 comment:first_comment]]
m = map [id:1 comment:first_comment]
res = [map [id:1 comment:first_comment] map [id:1 comment:first_comment]]
m = map [id:2 comment:first_comment]
res = [map [id:2 comment:first_comment] map [id:2 comment:first_comment] map [id:2 comment:first_comment]]
我期待res = [map [id:0 comment:first_comment] map [id:1 comment:first_comment] map [id:2 comment:first_comment]]
感谢您收看
答案 0 :(得分:-1)
根据行(https://golang.org/pkg/database/sql/#Rows.Scan)的文件:
扫描将当前行中的列复制到dest指向的值。
如果参数的类型为* [] byte,则Scan会在该参数中保存相应数据的副本。该副本由调用者拥有,可以无限期地修改和保留。可以通过使用* RawBytes类型的参数来避免副本;有关其使用的限制,请参阅RawBytes的文档。
如果参数的类型为* interface {},则Scan会复制底层驱动程序提供的值而不进行转换。如果值为[] byte类型,则复制并且调用者拥有结果。
在您的情况下,您使用RawBytes作为Scan的参数。这可能是你遇到的问题。尝试其他类型作为扫描功能的参数。