2012-12-29 20 views
1

我是Go新手,不確定如何解決此問題。在OOP中,我有一個基類動物和兩個貓和狗的子類。我想爲動物指定一個ToJson方法,它將適用於所有動物。在Go中將組合對象轉換爲json

我的問題是,當我打電話給dog.ToJson()我只得到狗的狗屬性,並沒有動物屬性。

如何讓ToJson按預期工作(即with recursion)?

編輯:更改了代碼以反映lbonn回答的建議,我無法按照自己的方式工作。 EDIT2:在質詢下面的代碼變化

package main 

import (
    "encoding/json" 
    "fmt" 
) 

type Animal struct { 
    Name string 
} 

type Cat struct { 
    CatProperty int64 
    Animal 
} 

type Dog struct { 
    DogProperty int64 
    Animal 
} 

func ToJson(i interface{}) []byte { 
     data,err := json.Marshal(i) 
    if err != nil { 
     panic("???") 
    } 
    return data 
} 

func main() { 
    dog := Dog{} 
    dog.Name = "rex" 
    dog.DogProperty = 2 
    fmt.Println(string(ToJson(dog))) 
    // Prints {"DogProperty":2} 
    // I want it to print {"Name":"rex","DogProperty":2} 
} 

回答

4

匿名字段的Json編碼從go 1中刪除。希望它會回到1.1。有關更多詳細信息,請參見https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/jYMHbEv44r4

所以,你可以使用標準庫得到現在(與去1)最好是http://play.golang.org/p/LncNFeN8ys

您可以隨時使用skelterjohn的補丁https://github.com/skelterjohn/json/支持匿名場,直到去1.1的發佈。

或者使用提示,從源代碼安裝修復此問題。看到https://codereview.appspot.com/6460044

+0

我使用'hg clone -r 492fdf07797e https:// code.google.com/p/go'更新到最新版本,並且一切都很好,我的json按照我的預期創建。感謝您的好消息。 – iancoleman

2

在此一致性,ToJson方法適用於匿名字段的DogAnimal。致電d.ToJson只是d.Animal.ToJson的可見性快捷方式。 GoLang Tutorials: Anonymous fields in struct

在這裏,我會寫一個函數,而不是一個方法(約Marshal一個簡單的包裝):

func ToJson(i interface{}) []byte { 
    data,err := json.Marshal(i) 
    if err != nil { 
     panic("???") 
    } 
    return data 
} 

這不是特定動物或狗,但它並沒有真正需要。

更一般地說,go中沒有真正的繼承概念。該語言中使用的對象範例與主流OOP完全不同,例如Java或C++。 Go FAQ提供了一些很好的說明。

+0

不幸的是,我仍然不理解......來自http://golang.org/pkg/encoding/json/#Marshal我看到「元帥遞歸地遍歷值」。我假設在我的例子中它應該創建包括DogProperty的Dog的json表示,並且(從遞歸)還包括來自Animal的Name屬性。但是當我打電話給Marshal時,結果不包含Name。你能幫我理解這個,最好通過發佈一個給出json {「DogProperty」:2,「Name」:「rex」}的例子嗎?另外,感謝有用的鏈接,它有助於澄清我對Go中組合如何工作的理解。 – iancoleman

+0

如果要打印狗的所有值,則需要在整個狗對象上調用'Marshal'。在你的例子中,'Marshal'在'Dog'內的匿名字段'Animal'上被調用。因此,它看不到包含在其中的「Dog」字段。您可以嘗試我在我的答案中發佈的代碼,並使用'fmt.Println(字符串(ToJson(d))',它將打印整個'Dog'。 – lbonn

+0

請參閱我編輯問題中的代碼,該代碼現在包含你的函數,它似乎沒有包含Name屬性,我只在我的輸出中獲得'{「DogProperty」:2}' – iancoleman