是否有一种惯用的方法将结构与其json编组逻辑分开?
通常:
package models
type Foo struct {
Name `json:"full_name"`
}
但我想分开关注点。我不希望json
包中的models
指定逻辑包含结构,也可能将json
逻辑放在另一个serializers
包中。你会怎么做到惯用的去?可能类似于rails
项目处理active_model_serializers
代码
答案 0 :(得分:2)
json
标签是否属于编组逻辑或json 模型是有争议的。我想说指定json标签只是描述json模型,因此它可能更好地驻留在你的Go模型旁边。
编组/解组逻辑在encoding/json
包本身中实现。如果需要自定义逻辑,可以通过实现json.Marshaler
和json.Unmarshaler
接口来指定/实现。这意味着为您的类型定义方法。在Go中,您只能为同一个包中的类型指定方法,因此如果您将模型与自定义解析逻辑分开,则解析包无法定义模型类型的方法。 Spec: Method declarations:
T
表示的类型称为接收器基本类型;它不能是指针或接口类型,必须在方法的相同包中声明。
话虽如此,您需要在不同的类型上定义自定义解析逻辑,并且您需要进一步的逻辑来映射/复制到模型类型作为解析逻辑的一部分。通过将模型与解析逻辑分离,您将失去更多的收益。
更进一步,您编组的结构类型可能包含未导出的字段 - 如果解析逻辑位于同一个包中 - 可以正确初始化。通过分离模型和逻辑,逻辑将初始化未导出的字段时会遇到麻烦。一种方法是提供导出的方法或函数,但随后将其导出到其他所有人,而不仅仅是解析逻辑。
我会说Go方式和最简单的方法是将模型和解析逻辑放在同一个包中。它仍然为您提供“小”分离可能性:您可以将类型定义放在一个文件中(例如model.go
),并且您可以放置自定义解析逻辑(实现json.Marshaler
和json.Unmarshaler
的方法)在另一个文件(例如parse.go
)但当然在同一个包中,但最好在一个地方(在一个文件中)看到一个类型及其所有方法。