英文:
Golang remap interface go-cache
问题
我有一个如下所示的结构体:
type Page struct {
title string
url string
}
还有一个结构体的映射:
var mostViewed = make(map[int]Page)
使用 go-cache,我将这个映射存储起来,并设置了一个 TTL 时间:
c.Set("data", mostViewed, 60*time.Minute)
但是,一旦我恢复了 "data" 键,如何将其重新赋值给一个映射呢?
a, _ := c.Get("data")
fmt.Printf("%+v\n", a)
输出: map[17:{title:xxx, url:yyy}]
我尝试了类似以下的方式:
z := map[int]Page{a}
有什么线索吗?就像是"重新映射"一个映射字符串。
英文:
I've got a struct like below:
type Page struct {
title string
url string
}
and a map of structs:
var mostViewed = make(map[int]Page)
With go-cache, I store the map with a TTL time.
c.Set("data", mostViewed, 60*time.Minute)
But, once I recover "data" key, how could I assing it back to a map?
a, _ := c.Get("data")
fmt.Printf("%+v\n", a)
out: map[17:{title:xxx, url:yyy}]
I tried something like:
z := map[int]Page{a}
Any clue? It's like "remapping" a mapped string.
答案1
得分: 1
你得到了一个interface{}
类型的返回值,但你知道它的实际类型,所以你需要使用类型断言将其转回map[int]Page
类型。这里有一个快速的外部资源:https://newfivefour.com/golang-interface-type-assertions-switch.html
以下是一个示例:
type Page struct {
title string
url string
}
func main() {
m := make(map[int]Page)
m[1] = Page{"hi", "there"}
iface := makeIface(m)
// 使用类型断言将其转回map类型
if mapAgain, ok := iface.(map[int]Page); ok {
// 确实是map[int]Page类型
fmt.Printf("%+v\n", mapAgain)
} else {
// 实际上不是map[int]Page类型
fmt.Println("oops")
}
// 或者使用类型开关,如果可能有多种类型
switch v := iface.(type) {
case map[int]Page:
// 是map[int]Page类型
fmt.Printf("%+v\n", v)
case string:
// 是字符串类型
fmt.Println(v)
default:
// 其他未考虑到的类型
}
}
func makeIface(m map[int]Page) interface{} {
return m
}
编辑:顺便提一下,你可能希望将你的map类型定义为map[int]*Page
,因为如果你这样做:
page := m[1]
page.url = "different"
fmt.Println(page) // 输出 url="different"
fmt.Println(m[1].url) // 输出 "there",保持不变
因为`page`将是map中的一个副本,而不是map中的`Page`本身。
英文:
You get an interface{}
type back, but you know what it is, so you need to use a type assertion to cast it back to a map[int]Page
. Here is a quick external resource. https://newfivefour.com/golang-interface-type-assertions-switch.html
Here is an example
https://play.golang.org/p/lGseg88K1m
type Page struct {
title string
url string
}
func main() {
m := make(map[int]Page)
m[1] = Page{"hi", "there"}
iface := makeIface(m)
// use type assertion to cast it back to a map
if mapAgain, ok := iface.(map[int]Page); ok {
// it really is a map[int]Page
fmt.Printf("%+v\n", mapAgain)
} else {
// its not actually a map[int]Page
fmt.Println("oops")
}
// alternatively use a type-switch if it could be multiple types
switch v := iface.(type) {
case map[int]Page:
//yay
fmt.Printf("%+v\n", v)
case string:
// its a string
fmt.Println(v)
default:
// something we didn't account for
}
}
func makeIface(m map[int]Page) interface{} {
return m
}
Edit: as a side note, you probably want to make your map type map[int]*Page
because if you did something like this:
page := m[1]
page.url = "different"
fmt.Println(page) // prints url="different"
fmt.Println(m[1].url) // remains unchanged
Because page
would be a copy of what is in the map, not the Page
in the map itself.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论