如何在Go语言中将map存入slice?解决重复引用问题
问题原因与解决方案
为什么slice里所有map都相同?
Go里的map是引用类型,你append到slice里的不是map的副本,而是指向这个map内存地址的引用。所以不管你append多少次,slice里的所有元素都指向同一个map实例。后续修改lookup时,所有slice元素都会同步变化,最终全变成最后一次修改的值。
解决方案
方法1:每次创建新的map
不要复用同一个lookup变量,每次填充前都新建一个map,这样append到slice里的都是独立的map引用:
data := make([]map[string]string, 0) // 第一次填充 lookup := make(map[string]string) lookup["name"] = "Alice" data = append(data, lookup) // 第二次填充,新建map lookup = make(map[string]string) lookup["name"] = "Bob" data = append(data, lookup) // 此时data[0]是{"name":"Alice"},data[1]是{"name":"Bob"}
方法2:append前创建map副本
如果必须复用lookup变量,每次append前要把当前lookup的键值对复制到新map里,再append这个副本:
lookup := make(map[string]string) data := make([]map[string]string, 0) // 第一次填充 lookup["age"] = "20" // 生成副本 copyMap := make(map[string]string) for k, v := range lookup { copyMap[k] = v } data = append(data, copyMap) // 清空lookup并填充新值 for k := range lookup { delete(lookup, k) } lookup["age"] = "30" // 再次生成副本 copyMap = make(map[string]string) for k, v := range lookup { copyMap[k] = v } data = append(data, copyMap)
关于自定义类型不匹配的问题
你定义的type data map[string]interface{}和map[string]string是不同类型,直接append会报错。解决方式有两种:
- 调整自定义类型为
type dataMap map[string]string(避免和变量名冲突),然后把lookup转换为该类型再append:
type dataMap map[string]string data := []dataMap{} lookup := make(map[string]string) lookup["id"] = "1001" data = append(data, dataMap(lookup))
- 如果要保留
map[string]interface{}类型,需要把lookup的键值对逐个转换后存入新的自定义类型map:
type data map[string]interface{} dataSlice := []data{} lookup := make(map[string]string) lookup["score"] = "90" // 转换类型 customMap := data{} for k, v := range lookup { customMap[k] = v } dataSlice = append(dataSlice, customMap)
内容的提问来源于stack exchange,提问作者Gamer
相关产品推荐
相关产品推荐

