繁体   English   中英

如何将接口转换为结构

[英]How to convert interface to struct

这是缓存的简化代码。 假设将Container放在包装中,所以对Member不了解。 我想将Member实例存储在Container中时,所以我将Container的空实例存储为outerType Container->GetMysql ,我用测试值填充了一个新变量(但在现实世界中,它是动态地用数据库的数据填充)。 然后在Put函数中,我将数据作为Cache存储在项中以备下次使用。 在“ Get我获取存储在项目中的数据。 在此之前,一切都很好。 我的问题是我要将Get的结果转换为成员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)
}

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

相反,如果您需要一个指向某物的指针(因此您可以在多个位置使用相同的指针,并在某处修改指向的值,它将对其他指针产生影响),则在接口值中“包装指针”。

因此,首先修改items字段,使其存储interface{}值而不是指针:

items map[string]interface{}

这意味着没有限制:您可以传递和存储指针,这不是问题。

接下来修改Get()以返回interface{}

func (cls *Container) Get(value string) interface{}{
    return cls.items[value]
}

同样在Put() ,不要使用interface{}的地址interface{}

func (cls *Container) Put(value string, a int64) {
    res := cls.GetMysql(value, a)
    cls.items[value] = res
}

并且您必须根据Get()返回的值对*Member进行断言。

现在对其进行测试:

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"))

即使我们没有调用Put() (在Go Playground上尝试Put() ,我们也会看到修改后的值:

&{0 Jack 11 0}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM