2015-11-02 98 views
1

我想創建一個結構的新實例,在運行時使用它的類型(reflect.TypeOf)。我已在StackOverflow How do you create a new instance of a struct from it's Type at runtime in Go?上跟隨此線程。下面是我的實現(也是在http://play.golang.org/p/BtX0d5Ytu8):GO運行時類型結構的新實例

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{"[email protected]", "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() 
} 

出於某種原因,我總是空的結構。我無法設置字段或修改。有人可以建議什麼是錯的?

+0

【如何初始化只給出一個接口樣本對象的列表?(HTTPS的可能重複://計算器。 com/questions/32916619/how-to-initialize-a-list-of-objects-given-only-an-interface-sample) – kenfire

回答

3

我回顧了你的代碼。當你的新類型與反映,你Value類型有一個值,需要調用Interface()來獲取新生成的值

校驗碼 http://play.golang.org/p/CHWSV8EG7D

+1

你也可以直接使用'reflect.ValueOf(ret).Interface()'。 –

+0

@FabianTamp我的錯誤,抵制錯誤類型'* UserInfo'而不是'UserInfo',所以現在不需要直接 –

0

上運行reflect.New(sometype。這時候)的接口導致反射的指針。某種類型的值。如果使用.Elem()將爲reflect.Value獲得直接值,該值爲空。對於這個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":"[email protected]","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":"[email protected]","name":"John Doe","_id":"142321"} 
main.UserInfo &{ } 
TypeOf(ret): *main.UserInfo 
ValueOf(ret): &{[email protected] John Doe 142321} 
Value: &{[email protected] John Doe 142321} 

在操場:https://play.golang.org/p/veTUho5D4d

相關問題