在Go中将组合对象转换为json

我是Go语言的新手,不确定如何解决此问题。 用OOP术语来说,我有动物的基类和猫和狗的两个子类。 我想为Animal指定一个ToJson方法,该方法适用于所有动物。</ p>

我的问题是,当我调用dog.ToJson()时,我只获得dog的Dog属性,而没有 动物属性。</ p>

如何使ToJson正常工作(即与递归)?</ p>

编辑:更改了代码以反映lbonn回答中的建议,我无法按自己的意愿去工作
edit2:代码更改后问题的一致性</ p>

 包主程序

import(
“ encoding / json”
“ fmt”

type动物结构{
名称字符串
}

type猫结构{
CatProperty int64
Animal
}

type狗结构{
DogProperty int64
Animal
}

func ToJson(i interface {})[] byte {
data,err:= json.Marshal(i)
if err!= nil {
panic(“ ???”)
}
返回数据\ n}

func main(){
dog:= Dog {}
dog.Name =“ rex”
dog.Dog 属性= 2
fmt.Println(string(ToJson(dog)))
//打印{“ DogProperty”:2}
//我希望它打印{“ Name”:“ rex”,“ DogProperty” :2}
}
</ code> </ pre>
</ div>

展开原文

原文

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}
}

2个回答



匿名字段的Json编码已从go 1中删除。希望它会在go 1.1中恢复。 请参见 https://groups.google.com/forum/? fromgroups =#!topic / golang-nuts / jYMHbEv44r4 了解更多详细信息。 </ p>

因此,现在使用标准库(执行go 1)可以获得的最佳效果是 http://play.golang.org/p/LncNFeN8ys </ p>

您始终可以使用skelterjohn的补丁 https://github.com/skelterjohn/json/ 支持匿名字段,直到1.1发行为止。 </ p>

或使用提示,从已解决此问题的源进行安装。 参见 https://codereview.appspot.com/6460044 </ p>
</ div>

展开原文

原文

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

doumo6356
doumo6356 我使用hg clone -r 492fdf07797e https://code.google.com/p/go新到了最新版本,一切都很好,我的json正在按预期的方式创建。 感谢您提供的信息。
7 年多之前 回复



此处, ToJson </ code>方法适用于的匿名字段 Animal </ code> >狗</代码>。 调用 d.ToJson </ code>只是 d.Animal.ToJson </ code>的可见性快捷方式。
GoLang教程:struct中的匿名字段 </ p>

在这里,我会写一个 函数而不是方法(的简单包装):</ p>

  func ToJson(i interface {})[] byte {
data, err:= json.Marshal(i)
如果err!= nil {
panic(“ ???”)
}
返回数据
}
</ code> </ pre>
\ n

这不是专门针对动物或狗,但实际上并不需要。</ p>

更一般而言,go中没有真正的继承概念。 该语言中使用的对象范式与主流的OOP(例如Java或C ++)完全不同。 常见问题解答提供了一些很好的说明。</ p>
</ div >

展开原文

原文

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.

dthl8036
dthl8036 哦,好吧,我使用的是开发版本,所以这才在这里起作用。 rputikar的答案解释了这个问题。
7 年多之前 回复
doubei2231
doubei2231 我在Ubuntu 12.04上使用go1.0.2。 请参阅play.golang.org/p/wntp7n7K8Y,该结果也无法提供理想的结果。
7 年多之前 回复
duanduanxi9441
duanduanxi9441 好吧,它确实在我的机器上运行,这很奇怪。 您正在使用哪个版本的go?
7 年多之前 回复
dsx5201
dsx5201 请查看我对问题代码的编辑,该问题现在包括您的功能。 它似乎没有包含Name属性,我在输出中仅得到{“ DogProperty”:2}
7 年多之前 回复
douran6443
douran6443 如果要打印出dog的所有值,则需要在整个dog对象上调用Marshal。 在您的示例中,在Dog内部的匿名字段Animal上调用了元帅。 因此,它看不到其中不包含Dog的字段。 您可以尝试在答案中发布的代码,并使用fmt.Println(string(ToJson(d))),它将打印出整个Dog。
7 年多之前 回复
duanba7653
duanba7653 不幸的是,我仍然不了解...从golang.org/pkg/encoding/json/#Marshal中,我看到“ Marshal递归遍历值v”。 我假设在我的示例中,它应该创建dog的json表示形式,包括DogProperty,并且(从递归中)还包括Animal的Name属性。 但是当我打电话给元帅时,结果不包括姓名。 您能帮我理解这一点吗,最好是发布一个给出json {“ DogProperty”:2,“ Name”:“ rex”}的示例吗? 另外,感谢您提供的有用链接,它有助于阐明我对Go中合成工作原理的理解。
7 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问