Serialization Golang中的序列化模型
我试图将我的代码划分为模型和序列化程序,其思想是有一个定义的序列化程序来处理所有json职责,即分离关注点。我还希望能够调用模型对象Serialization Golang中的序列化模型,serialization,go,Serialization,Go,我试图将我的代码划分为模型和序列化程序,其思想是有一个定义的序列化程序来处理所有json职责,即分离关注点。我还希望能够调用模型对象obj.Serialize(),以获取序列化程序结构obj,然后对其进行封送处理。因此,我提出了以下设计。为了避免循环导入,我必须在序列化程序中使用接口,这导致在模型中使用getter。我已经读到getter/setter不是惯用的go代码,我不希望所有模型都有“样板”getter代码。对于我想要完成的任务,有没有更好的解决方案,请记住我想要分离关注点和obj.Se
obj.Serialize()
,以获取序列化程序结构obj,然后对其进行封送处理。因此,我提出了以下设计。为了避免循环导入,我必须在序列化程序中使用接口,这导致在模型中使用getter。我已经读到getter/setter不是惯用的go代码,我不希望所有模型都有“样板”getter代码。对于我想要完成的任务,有没有更好的解决方案,请记住我想要分离关注点和obj.Serialize()
models/a.go
import "../serializers"
type A struct {
name string
age int // do not marshal me
}
func (a *A) Name() string {
return a.name
}
// Serialize converts A to ASerializer
func (a *A) Serialize() interface{} {
s := serializers.ASerializer{}
s.SetAttrs(a)
return s
}
// AInterface used to get Post attributes
type AInterface interface {
Name() string
}
// ASerializer holds json fields and values
type ASerializer struct {
Name `json:"full_name"`
}
// SetAttrs sets attributes for PostSerializer
func (s *ASerializer) SetAttrs(a AInterface) {
s.Name = a.Name()
}
序列化程序/a.go
import "../serializers"
type A struct {
name string
age int // do not marshal me
}
func (a *A) Name() string {
return a.name
}
// Serialize converts A to ASerializer
func (a *A) Serialize() interface{} {
s := serializers.ASerializer{}
s.SetAttrs(a)
return s
}
// AInterface used to get Post attributes
type AInterface interface {
Name() string
}
// ASerializer holds json fields and values
type ASerializer struct {
Name `json:"full_name"`
}
// SetAttrs sets attributes for PostSerializer
func (s *ASerializer) SetAttrs(a AInterface) {
s.Name = a.Name()
}
看起来您实际上是在尝试在内部结构和json之间进行转换。我们可以从利用json库开始 如果您希望某些库以某种方式处理结构字段,则可以使用标记。此示例显示了json标记如何告诉json不要将字段
age
封送到json中,如果字段jobTitle
不为空,则只添加该字段,并且该字段jobTitle
在json中实际上被称为title
。当go中的结构包含大写(导出)字段,但连接到的json api使用小写键时,此重命名功能非常有用
type A struct {
Name string
Age int `json:"-"`// do not marshal me
location string // unexported (private) fields are not included in the json marshal output
JobTitle string `json:"title,omitempty"` // in our json, this field is called "title", but we only want to write the key if the field is not empty.
}
如果您需要预计算一个字段,或者只是在一个结构的json输出中添加一个不是该结构的成员的字段,我们可以通过一些魔术来做到这一点。当json对象再次解码为golang结构时,不适合的字段(在检查重命名字段和大小写差异后)将被忽略
// AntiRecursionMyStruct avoids infinite recursion in MashalJSON. Only intended for the json package to use.
type AntiRecursionMyStruct MyStruct
// MarshalJSON implements the json.Marshaller interface. This lets us marshal this struct into json however we want. In this case, we add a field and then cast it to another type that doesn't implement the json.Marshaller interface, and thereby letting the json library marshal it for us.
func (t MyStruct) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
AntiRecursionMyStruct
Kind string // the field we want to add, in this case a text representation of the golang type used to generate the struct
}{
AntiRecursionMyStruct: AntiRecursionMyStruct(t),
Kind: fmt.Sprintf("%T", MyStruct{}),
})
}
请记住,json将只包括导出(大写)的结构成员。我已经多次犯过这个错误
一般来说,如果事情看起来太复杂,可能有更好的方法