英文:
Converting composed objects to json in Go
问题
我是Go的新手,对于如何解决这个问题还不确定。从面向对象的角度来看,我有一个Animal的基类和两个子类Cat和Dog。我想为Animal指定一个ToJson方法,该方法适用于所有动物。
我的问题是,当我调用dog.ToJson()时,我只得到了dog的Dog属性,而没有Animal的属性。
我该如何使ToJson按预期工作(即递归)?
编辑:根据lbonn的答案中的建议更改了代码,但无法按照我想要的方式工作。
编辑2:在代码更改后的问题中保持一致
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)))
// 输出 { "DogProperty": 2 }
// 我希望它输出 { "Name": "rex", "DogProperty": 2 }
}
英文:
I am new to Go and am unsure about how to approach this problem. In OOP terms, I have a base class of Animal and two subclasses of Cat and Dog. I want to specify a ToJson method for Animal which will work for all animals.
My problem is that when I call dog.ToJson() I only get the Dog properties of dog and none of the Animal properties.
How can I make ToJson work as expected (ie with recursion)?
edit: Changed code to reflect suggestions in answer by lbonn, which I could not get to work how I want it to.
edit2: consistency in question following code change
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}
}
1: http://golang.org/pkg/encoding/json/#Marshal "with recursion"
答案1
得分: 4
匿名字段的Json编码在go 1中被删除了。希望在go 1.1中会重新加入。更多详情请参见https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/jYMHbEv44r4。
所以现在你能得到的最好结果(在go 1中)是http://play.golang.org/p/LncNFeN8ys。
你可以始终使用skelterjohn的补丁https://github.com/skelterjohn/json/来支持匿名字段,直到go 1.1发布。
或者使用tip(tip.golang.org),从源代码安装,该问题已经修复。请参见https://codereview.appspot.com/6460044。
英文:
Json encoding of anonymous fields was dropped from go 1. Hopefully it will be back in go 1.1. See https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/jYMHbEv44r4 for more details.
So the best you can get with the standard library right now (with go 1) is http://play.golang.org/p/LncNFeN8ys
You can always use skelterjohn's patch https://github.com/skelterjohn/json/ to support anonymous fields till go 1.1 is released.
Or use tip, installing from source that has this issue fixed. see https://codereview.appspot.com/6460044
答案2
得分: 2
这里,ToJson
方法适用于Dog
的匿名字段Animal
。调用d.ToJson
只是d.Animal.ToJson
的一个可见性快捷方式。
GoLang教程:结构体中的匿名字段
在这里,我会写一个函数而不是一个方法(一个简单的Marshal
的包装器):
func ToJson(i interface{}) []byte {
data,err := json.Marshal(i)
if err != nil {
panic("???")
}
return data
}
这与动物或狗无关,但实际上并不需要。
更一般地说,Go语言中没有真正的继承概念。该语言中使用的对象范式与主流的面向对象编程(如Java或C++)有很大的区别。Go FAQ提供了一些关于此的很好的澄清。
英文:
Here, the ToJson
method applies to the anonymous field Animal
of Dog
. The call d.ToJson
is only a visibility shortcut to d.Animal.ToJson
.
GoLang Tutorials: Anonymous fields in struct
Here, I would write a function instead of a method (a simple wrapper around Marshal
):
func ToJson(i interface{}) []byte {
data,err := json.Marshal(i)
if err != nil {
panic("???")
}
return data
}
This is not specific to animals or dogs but it doesn't really need to.
More generally, there is no real notion of inheritance in go. The object paradigm used in the language is quite different from mainstream OOP, like in Java or C++. The Go FAQ provides some good clarifications about it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论