英文:
How to upsert into concurrent map while iterating over regular map?
问题
我需要一个以string
为键,以唯一(无重复项)的int64
数组为值的映射,所以我决定使用以下代码,以便值可以充当一个集合。
var customerCatalog = make(map[string]map[int64]bool)
上述映射已经填充了一些数据。现在,我正在尝试通过读取上述常规的customerCatalog
映射来填充我的并发映射(concurrent map),但是我遇到了错误:
for k, v := range customerCatalog {
r.customerCatalog.Upsert(k, v, func(exists bool, valueInMap interface{}, newValue interface{}) interface{} {
typedNewValue := newValue.([]int64)
if !exists {
return typedNewValue
}
typedValueInMap := valueInMap.([]int64)
return append(typedValueInMap, typedNewValue...)
})
}
这是我遇到的错误。我正在使用如下所示的upsert方法:链接
panic: interface conversion: interface {} is map[int64]bool, not []int64
我做错了什么?
英文:
I need to have a map of string
as key and unique (no dupes) int64
array as value so I decided to use something like below so that value can act as a set.
var customerCatalog = make(map[string]map[int64]bool)
Above map is populated with some data in it. Now I am trying to populate my concurrent map in golang by reading above regular customerCatalog
map but I am getting error:
for k, v := range customerCatalog {
r.customerCatalog.Upsert(k, v, func(exists bool, valueInMap interface{}, newValue interface{}) interface{} {
typedNewValue := newValue.([]int64)
if !exists {
return typedNewValue
}
typedValueInMap := valueInMap.([]int64)
return append(typedValueInMap, typedNewValue...)
})
}
This is the error I am getting. I am using upsert method as shown here
panic: interface conversion: interface {} is map[int64]bool, not []int64
What is wrong I am doing?
答案1
得分: 0
我相信你的问题的一个最小、可重现的示例如下所示(playground):
conMap := cmap.New()
v := map[int64]bool{}
updateItemFn := func(exist bool, valueInMap interface{}, newValue interface{}) interface{} {
_ = newValue.([]int64)
return nil
}
conMap.Upsert("foo", v, updateItemFn)
注意:我已经删除了循环等内容,因为这与 panic 无关。但是你应该注意,由于循环遍历的是 map[string]map[int64]bool
类型,所以 v
的类型将是 map[int64]bool
。
Upsert
函数在地图中查找键,然后将其和你传入的 value
一起传递给函数。
因此,你的函数接收到的是一个 map[int64]bool
,它首先断言这是一个 []int64
(这将失败,因为它不是)。要解决这个问题,你需要将 map[int64]bool
转换为 []int64
。这可以在调用 Upsert
之前或在你的 UpsertCb
实现中完成,如下所示(playground):
conMap := cmap.New()
conMap.Set("foo", []int64{5, 6})
v := map[int64]bool{
1: true,
}
updateItemFn := func(exist bool, valueInMap interface{}, newValue interface{}) interface{} {
m := newValue.(map[int64]bool)
a := make([]int64, 0, len(m))
for k := range m {
a = append(a, k)
}
if valueInMap == nil { // 新值!
return a
} else {
typedValueInMap := valueInMap.([]int64)
return append(typedValueInMap, a...)
}
return a
}
conMap.Upsert("foo", v, updateItemFn)
fmt.Println(conMap.Get("foo"))
上面的示例保持简单,以说明问题;实际上,你可能希望将所有的值添加到一个映射中,以避免重复。
英文:
I believe a minimal, reproducible, example of your issue would be as follows (playground):
conMap := cmap.New()
v := map[int64]bool{}
updateItemFn := func(exist bool, valueInMap interface{}, newValue interface{}) interface{} {
_ = newValue.([]int64)
return nil
}
conMap.Upsert("foo", v, updateItemFn)
Note: I have stripped out the loop etc because that is irrelevant to the panic. However you should note that because the loop iterates over a map[string]map[int64]bool
the type of v
will be map[int64]bool
.
The Upsert
function looks up the key in the map and then passes it and the value
you passed in to the function.
So your function is receiving a map[int64]bool
and the first thing it does is to assert that this is a []int64
(which will fail because it's not). To fix this you need to convert the map[int64]bool
into a []int64
. This could be done before calling the Upsert
or within your implementation of UpsertCb
as shown here (playground):
conMap := cmap.New()
conMap.Set("foo", []int64{5, 6})
v := map[int64]bool{
1: true,
}
updateItemFn := func(exist bool, valueInMap interface{}, newValue interface{}) interface{} {
m := newValue.(map[int64]bool)
a := make([]int64, 0, len(m))
for k := range m {
a = append(a, k)
}
if valueInMap == nil { // New value!
return a
} else {
typedValueInMap := valueInMap.([]int64)
return append(typedValueInMap, a...)
}
return a
}
conMap.Upsert("foo", v, updateItemFn)
fmt.Println(conMap.Get("foo"))
The above has been kept simple to demonstrate the point; in reality you may want to add all of the values into a map so as to avoid duplicates.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论