Search code examples
cachinggobeego

How do I convert this cache item back to a slice of maps?


I'm still new to Go and trying to use Beego's cache. I can put a []map[string]string into the cache but can't figure out how to convert the value back to a []map[string]string.

For instance, to put the item in the cache:

m:=make([]map[string]string)
// add items to the slice of maps
.......
// cache it
if err := c.Put("key", m, 100); err != nil {
    fmt.Println(err)
}
// retrieve it
n := c.Get("key")
fmt.Println(reflect.TypeOf(n)) // ==>string

// failed attempt
a := n.([]map[string]string)
fmt.Println(a) // panic: interface conversion: interface is string, not []map[string]string

How do I convert n to a slice of maps?


Solution

  • well digging into the code seems like even if it says interface{} what it does it actually squash everything to []byte

    https://github.com/astaxie/beego/blob/master/cache/memcache/memcache.go#L77

    and when it Does the Get convert everything to string

    https://github.com/astaxie/beego/blob/master/cache/memcache/memcache.go#L61

    So you need to Marshal / Unmarshal the data structure yourself.

    See this example and substitute your calls and error check with the dummies one provided:

    http://play.golang.org/p/9z3KcOlgAx

    package main
    
    import (
        "bytes"
        "encoding/json"
        "log"
    )
    
    var cache map[string]string = make(map[string]string)
    
    func Put(key, value string) {
        cache[key] = value
    }
    
    func Get(key string) string {
        return cache[key]
    }
    
    func main() {
    
        m := map[string]string{
            "A": "1",
            "B": "2",
        }
        if b, err := json.Marshal(m); err != nil {
            log.Fatal(err)
        } else {
            Put("myKey", string(b))
        }
    
        b := bytes.NewBufferString(Get("myKey"))
    
        var mm map[string]string
        if err := json.Unmarshal(b.Bytes(), &mm); err != nil {
            log.Fatal(err)
        }
    
        log.Printf("%#v", mm)
    }