Golang重新映射接口go-cache

huangapple go评论131阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2017年5月17日 03:15:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/44009786.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定