为了账号安全,请及时绑定邮箱和手机立即绑定

如何将接口转换为结构

如何将接口转换为结构

Go
慕少森 2023-06-12 16:05:20
这是缓存的简化代码。假设Container放在一个包里,所以它不知道Member。虽然我想在 Container 中存储 Member 的实例,所以我在 Container 中存储一个空的 Member 实例作为outerType. 在 中Container->GetMysql,我通过测试值填充一个新变量(但在现实世界中,它通过数据库的数据动态填充)。然后在函数中Put,我将数据存储在项目中作为缓存以供下次使用。在Get我得到存储在项目中的数据。在此之前一切都很好。我的问题是我想将 Get 的结果转换为 Member 的类型m = res.(Member)。我如何将它转换为 Member 的实例我发现了很多关于这个主题的问题,但没有一个解决了我的问题有关更多详细信息:我想要Get返回数据及其在项目中存储位置的指针。因此,如果我得到同一成员的一些变量,其中一个的变化会显示在其他成员中package mainimport (    "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)}
查看完整描述

1 回答

?
慕后森

TA贡献1802条经验 获得超5个赞

您几乎不应该使用指向接口的指针。我的建议是永远不要使用它,当你需要它时,你就会知道。


相反,如果你需要一个指向某物的指针(这样你就可以在多个地方拥有相同的指针,因此在某处修改指向的值,它会对其他地方产生影响),在接口值中“包装指针”。


因此,首先修改该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}


查看完整回答
反对 回复 2023-06-12
  • 1 回答
  • 0 关注
  • 138 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信