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

GO 中运行时类型的新结构实例

GO 中运行时类型的新结构实例

Go
慕标5832272 2021-11-22 10:30:39
我正在尝试创建一个结构的新实例,在运行时使用它的类型 (reflect.TypeOf)。我在 StackOverflow 上关注了这个线程你如何在 Go 中在运行时从它的类型创建一个结构的新实例?. 这是我的实现(也在http://play.golang.org/p/BtX0d5Ytu8):package mainimport (    "fmt"    "reflect"    "encoding/json"    "bytes")type UserInfo struct {    Email    string `json:"email"`    FullName string `json:"name"`    ID       string `json:"_id"`}func main() {    fmt.Println("Hello, playground")    db := DBEngine{}    db.DB = make(map[string][]byte)    db.Register(UserInfo{})    db.Put("142321", UserInfo{"jdoe@acme.com", "John Doe", "142321"})    ret := db.Get("142321")    fmt.Println("TypeOf(ret):", reflect.TypeOf(ret))    fmt.Println("ValueOf(ret):", reflect.ValueOf(ret))    fmt.Println("Value:", ret)}type DBEngine struct {    Template interface{}    DB       map[string][]byte}func (db *DBEngine) Register(v interface{}) {    db.Template = v}//Set User defined objectfunc (db *DBEngine) Put(key string, v interface{}) {    res, _ := json.Marshal(v)    db.DB[key] = res}//Return user defined objectfunc (db *DBEngine) Get(key string) interface{} {    decoder := json.NewDecoder(bytes.NewReader(db.DB[key]));    fmt.Println("Value []byte:", string(db.DB[key]))    ret := reflect.New(reflect.TypeOf(db.Template)).Elem()    fmt.Println(reflect.TypeOf(db.Template), ret)    decoder.Decode(ret)    return ret.Interface()}出于某种原因,我总是得到空结构。我无法设置字段或修改。有人可以提出什么问题吗?
查看完整描述

2 回答

?
慕森卡

TA贡献1806条经验 获得超8个赞

我查看了您的代码。当你用reflect新建一个类型时,你在Value类型中获得了一个值,需要调用Interface()以获取该新生成值的接口

检查代码 http://play.golang.org/p/CHWSV8EG7D


查看完整回答
反对 回复 2021-11-22
?
慕的地6264312

TA贡献1817条经验 获得超6个赞

在运行时reflect.New(sometype) 导致reflect.Value of sometype 的指针。如果您使用 .Elem() 将直接获得为空的反射值。对于这个 main.UserInfo{}。


//Return user defined object

func (db *DBEngine) Get(key string) interface{} {

    decoder := json.NewDecoder(bytes.NewReader(db.DB[key]));

    fmt.Println("Value []byte:", string(db.DB[key]))

    ret := reflect.New(reflect.TypeOf(db.Template)).Elem()//<--wrong

    fmt.Println(reflect.TypeOf(db.Template), ret)

    decoder.Decode(ret)

    return ret.Interface()

}

//print

//Hello, playground

//Value []byte: {"email":"jdoe@acme.com","name":"John Doe","_id":"142321"}

//main.UserInfo {  }

//TypeOf(ret): main.UserInfo

//ValueOf(ret): {  }

//Value: {  }

要获取 *sometype 值,请使用 .Interface(),这样您就可以解码了。看:


//Return user defined object

func (db *DBEngine) Get(key string) interface{} {

    decoder := json.NewDecoder(bytes.NewReader(db.DB[key]));

    fmt.Println("Value []byte:", string(db.DB[key]))

    retValue := reflect.New(reflect.TypeOf(db.Template))

    retInter := retValue.Interface()//<-- 

    fmt.Println(reflect.TypeOf(db.Template), retInter)

    decoder.Decode(retInter)

    return retInter

}

结果:


Hello, playground

Value []byte: {"email":"jdoe@acme.com","name":"John Doe","_id":"142321"}

main.UserInfo &{  }

TypeOf(ret): *main.UserInfo

ValueOf(ret): &{jdoe@acme.com John Doe 142321}

Value: &{jdoe@acme.com John Doe 142321}

在操场上:https : //play.golang.org/p/veTUho5D4d


查看完整回答
反对 回复 2021-11-22
  • 2 回答
  • 0 关注
  • 145 浏览
慕课专栏
更多

添加回答

举报

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