gpt4 book ai didi

serialization - 在 Golang 中序列化模型

转载 作者:IT王子 更新时间:2023-10-29 01:59:08 25 4
gpt4 key购买 nike

我试图将我的代码分成模型和序列化器,并希望定义序列化器来处理所有 json 职责,即关注点分离。我还希望能够调用模型对象 obj.Serialize() 来获取我随后可以编码的序列化程序结构 obj。因此,我想出了以下设计。为了避免循环导入,我不得不在我的序列化器中使用接口(interface),这导致在我的模型中使用 getter。我读到 getters/setters 不是惯用的 go 代码,我不希望在我的模型中使用“样板”getter 代码。对于我想要完成的事情,是否有更好的解决方案,请记住我想要分离关注点和 obj.Serialize()

src/
models/
a.go
serializers/
a.go

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
}

serializers/a.go

// 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 将仅包含您导出的(大写的)结构成员。我已经多次犯过这个错误。

一般来说,如果某件事看起来太复杂,可能有更好的方法。

关于serialization - 在 Golang 中序列化模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34773908/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com