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

huangapple go评论80阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2012年12月29日 11:49:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/14078527.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定