2013-08-17 48 views
5

Here is the code解組上反射的值

package main 

import (
    "fmt" 

    "encoding/json" 
    "reflect" 
) 

var (
    datajson []byte 
    //ref mapp 
) 

type mapp map[string]reflect.Type 

type User struct { 
    Name string 
    //Type map[string]reflect.Type 
} 

func MustJSONEncode(i interface{}) []byte { 
    result, err := json.Marshal(i) 
    if err != nil { 
     panic(err) 
    } 
    return result 
} 
func MustJSONDecode(b []byte, i interface{}) { 
    err := json.Unmarshal(b, i) 
    if err != nil { 
     panic(err) 
    } 

} 
func Store(a interface{}) { 
    datajson = MustJSONEncode(a) 
    //fmt.Println(datajson) 
} 

func Get(a []byte, b interface{}) { 
    objType := reflect.TypeOf(b).Elem() 
obj := reflect.New(objType) 
//fmt.Println(obj) 
MustJSONDecode(a, &obj) 
fmt.Printf("%s", obj) 
    } 

func main() { 

    dummy := &User{} 
    david := User{Name: "DavidMahon"} 

    Store(david) 
    Get(datajson, dummy) 

} 

在Get函數

func Get(a []byte, b interface{}) { 
    objType := reflect.TypeOf(b).Elem() 
obj := reflect.New(objType) 
//fmt.Println(obj) 
MustJSONDecode(a, &obj) 
fmt.Printf("%s", obj) 
    } 

我無法將JSON解組爲基礎對象類型。

這裏有什麼問題嗎?我很困在這裏。非常簡單但很難弄清楚的東西。

感謝

UPDATE ::這個問題的目標是中檢索進去功能傳遞類型的完全形成對象。

Nick在下面的評論中提到的方法並沒有讓我知道我以前已經嘗試過的實際對象。我反正檢索數據(即使對象具有遞歸對象下面)在地圖上像這樣

func Get(a []byte) { 
    var f interface{} 

    //buf := bytes.NewBuffer(a) 
    //v := buf.String() 
    //usr := &User{} 

    MustJSONDecode(a, &f) 
    fmt.Printf("\n %v \n", f) 
} 

不過,我需要實際的對象返回不僅僅是數據。類似於user := &User{"SomeName"},我需要從Unmarshall回來的對象user。訣竅在某處反思,但不知道如何。

+0

反映不會做你認爲會的事。你不能用它構造一個任意的對象。你可能可以用反射和不安全的方法拼湊一些東西,但是你真的應該重新思考你正在嘗試做什麼。 –

+0

謝謝我關閉此主題。感謝您抽出時間。爲你的答案+1了。 – Minty

回答

3

我很困惑,爲什麼你要做到這一點,但這裏是如何解決它

func Get(a []byte, b interface{}) { 
    objType := reflect.TypeOf(b).Elem() 
    obj := reflect.New(objType).Interface() 
    //fmt.Println(obj) 
    MustJSONDecode(a, &obj) 
    fmt.Printf("obj = %#v\n", obj) 
} 

注意調用Interface()

Playground link

在我看來,那你要了很多麻煩,使空&User當你已經有一個在b,如

func Get(a []byte, b interface{}) { 
    MustJSONDecode(a, &b) 
    fmt.Printf("obj = %#v\n", b) 
} 

,但我想有這個計劃在這裏並不明顯!

+0

謝謝,但我已經試過thsat技巧。這有兩個問題。 – Minty

+0

1.它不適用於遞歸對象類型。這是對象內部的對象,2.返回的數據不是在Get函數中發送的類型對象。那是棘手的部分。我更新了我的問題以澄清這一點。 – Minty

+0

什麼返回對象?你不返回一個對象。 b已經是正確的類型,通過調用MustJSONDecode來填充。 –

1

reflect.New(objType)返回一個reflect.Value這不是你傳遞的接口。根據文檔Value它是一個只有未導出域的結構。 json軟件包無法使用未導出的字段。由於它不是你傳入的同一個對象,它甚至不是json可編碼/可解碼的json包會失敗。

您可能會在嘗試使用反射包時發現Laws of Reflection文章有用。

+0

感謝您的參考。我讀了三次,但有人認爲我注意到這篇文章(其中btw非常直觀)不會談論從其他對象創建對象。作爲開發者自由裁量權的一部分,作者可能會保留這一點。 – Minty

+1

您無法真正使用反射來按照您描述的方式創建特定類型的對象。您可以使用反射來查看* if *對象是特定類型的對象,但不能構造任意類型。 –