[英]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.