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

我正在尝试创建一个结构的新实例,在运行时使用它的类型 (reflect.TypeOf)。我在 StackOverflow 上关注了这个线程你如何在 Go 中在运行时从它的类型创建一个结构的新实例?. 这是我的实现(也在http://play.golang.org/p/BtX0d5Ytu8):


package main


import (

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

func (db *DBEngine) Put(key string, v interface{}) {

    res, _ := json.Marshal(v)

    db.DB[key] = res

}


//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()

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

    decoder.Decode(ret)

    return ret.Interface()

}

出于某种原因,我总是得到空结构。我无法设置字段或修改。有人可以提出什么问题吗?


慕标5832272
浏览 146回答 2
2回答

慕森卡

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

慕的地6264312

在运行时reflect.New(sometype) 导致reflect.Value of sometype 的指针。如果您使用 .Elem() 将直接获得为空的反射值。对于这个 main.UserInfo{}。//Return user defined objectfunc (db *DBEngine) Get(key string) interface{} {&nbsp; &nbsp; decoder := json.NewDecoder(bytes.NewReader(db.DB[key]));&nbsp; &nbsp; fmt.Println("Value []byte:", string(db.DB[key]))&nbsp; &nbsp; ret := reflect.New(reflect.TypeOf(db.Template)).Elem()//<--wrong&nbsp; &nbsp; fmt.Println(reflect.TypeOf(db.Template), ret)&nbsp; &nbsp; decoder.Decode(ret)&nbsp; &nbsp; return ret.Interface()}//print//Hello, playground//Value []byte: {"email":"jdoe@acme.com","name":"John Doe","_id":"142321"}//main.UserInfo {&nbsp; }//TypeOf(ret): main.UserInfo//ValueOf(ret): {&nbsp; }//Value: {&nbsp; }要获取 *sometype 值,请使用 .Interface(),这样您就可以解码了。看://Return user defined objectfunc (db *DBEngine) Get(key string) interface{} {&nbsp; &nbsp; decoder := json.NewDecoder(bytes.NewReader(db.DB[key]));&nbsp; &nbsp; fmt.Println("Value []byte:", string(db.DB[key]))&nbsp; &nbsp; retValue := reflect.New(reflect.TypeOf(db.Template))&nbsp; &nbsp; retInter := retValue.Interface()//<--&nbsp;&nbsp; &nbsp; fmt.Println(reflect.TypeOf(db.Template), retInter)&nbsp; &nbsp; decoder.Decode(retInter)&nbsp; &nbsp; return retInter}结果:Hello, playgroundValue []byte: {"email":"jdoe@acme.com","name":"John Doe","_id":"142321"}main.UserInfo &{&nbsp; }TypeOf(ret): *main.UserInfoValueOf(ret): &{jdoe@acme.com John Doe 142321}Value: &{jdoe@acme.com John Doe 142321}在操场上:https : //play.golang.org/p/veTUho5D4d
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go