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?
CodePudding user response:
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.