我正试图在运行时使用结构的类型(reflect.TypeOf)创建结构的新实例。我在StackOverflow上关注了这个线程如何从中创建一个结构的新实例';s在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()
}
由于某种原因,我总是得到空的结构。我无法设置字段或修改。有人能提出问题吗?
我查看了您的代码。当你用reflect新建一个类型时,你在Value
类型中得到了一个值,需要调用Interface()
来获得新生成的值的接口
检查代码http://play.golang.org/p/CHWSV8EG7D
运行时反射。新建(sometype)会导致一个用于反射的指针。某个类型的值。如果使用.Elm(),将获得反射的直接值。值为空。对于这个主管道。用户信息{}。
//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: { }
对于get*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