猿问

如何将接口转换为结构

这是缓存的简化代码。假设Container放在一个包里,所以它不知道Member。虽然我想在 Container 中存储 Member 的实例,所以我在 Container 中存储一个空的 Member 实例作为outerType. 在 中Container->GetMysql,我通过测试值填充一个新变量(但在现实世界中,它通过数据库的数据动态填充)。然后在函数中Put,我将数据存储在项目中作为缓存以供下次使用。在Get我得到存储在项目中的数据。在此之前一切都很好。我的问题是我想将 Get 的结果转换为 Member 的类型m = res.(Member)。我如何将它转换为 Member 的实例我发现了很多关于这个主题的问题,但没有一个解决了我的问题


有关更多详细信息:我想要Get返回数据及其在项目中存储位置的指针。因此,如果我得到同一成员的一些变量,其中一个的变化会显示在其他成员中


package main


import (

    "fmt"

    "reflect"

)


type Member struct {

    Id     int

    Name   string

    Credit int

    Age    int

}


type Container struct {

    outerType interface{}

    items     map[string]*interface{}

}


func (cls *Container)GetMysql(s string, a int64) interface{}{

    obj := reflect.New(reflect.TypeOf(cls.outerType))

    elem := obj.Elem()

    //elem := reflect.ValueOf(o).Elem()

    if elem.Kind() == reflect.Struct {

        f := elem.FieldByName("Name")

        f.SetString(s)

        f = elem.FieldByName("Credit")

        f.SetInt(a)

    }

    return obj.Interface()

}


func (cls *Container)Get(value string) *interface{}{

    return cls.items[value]

}


func (cls *Container)Put(value string, a int64) {

    res := cls.GetMysql(value, a)

    cls.items[value] = &res

}


func main() {

    c := Container{outerType:Member{}}

    c.items = make(map[string]*interface{})

    c.Put("Jack", 500)

    res := c.Get("Jack")

    fmt.Println(*res)

    m := &Member{}

    m = res.(Member) // Here is the problem. How to convert ?

    fmt.Println(m)

}


慕少森
浏览 139回答 1
1回答

慕后森

您几乎不应该使用指向接口的指针。我的建议是永远不要使用它,当你需要它时,你就会知道。相反,如果你需要一个指向某物的指针(这样你就可以在多个地方拥有相同的指针,因此在某处修改指向的值,它会对其他地方产生影响),在接口值中“包装指针”。因此,首先修改该items字段,使其存储interface{}值而不是指针:items map[string]interface{}这意味着没有限制:您可以传递和存储指针,这不是问题。接下来修改Get()返回interface{}:func (cls *Container) Get(value string) interface{}{    return cls.items[value]}并且在 中Put(),不要获取以下地址interface{}:func (cls *Container) Put(value string, a int64) {    res := cls.GetMysql(value, a)    cls.items[value] = res}并且您必须*Member根据 返回的值进行类型断言Get()。现在测试它:c := Container{outerType: Member{}}c.items = make(map[string]interface{})c.Put("Jack", 500)res := c.Get("Jack")fmt.Println(res)m := res.(*Member) // Here is the problem. How to convert ?fmt.Println(m)输出(在Go Playground上尝试):&{0 Jack 500 0}&{0 Jack 500 0}现在,如果您要修改以下字段m:m.Credit = 11然后从缓存中获取值:fmt.Println(c.Get("Jack"))我们将看到修改后的值,即使我们没有调用(在Go PlaygroundPut()上尝试):&{0 Jack 11 0}
随时随地看视频慕课网APP

相关分类

Go
我要回答