【问题标题】:Conversion of Go struct fields with tags使用标签转换 Go 结构字段
【发布时间】:2020-11-23 00:51:38
【问题描述】:

我真的被围棋中一个看似微不足道的问题困在这里: 我有一个 Golang 微服务,它以 json 格式输出数据。假设我有一个带有 json 标记的简单结构:

type Result struct {
    Name string `json:"name"`
    Age int `json:"age"`
}

在实际从数据库中提取数据的代码部分,我有一个非常相似的结构,如下所示:

type ResultBackend struct {
    Name string `bson:"fullName"`
    Age int `bson:"age"`
}

结构字段是相似的,除了不同的标签。我想保持简单,只从后端服务(ResultBackend)返回一个结构,然后可以作为 JSON 响应发送,如下所示:

func process() Result {
    var result ResultBackend
    ... do a MongoDB query here and store results in result variable ...
    return result
}

这肯定行不通,因为我们这里有两个不同的结构。 当然,一种解决方案是将两个标签嵌入到一个结构中,如下所示:

type Result struct {
    Name string `json:"name" bson:"fullName"`
    Age int `json:"age bson:"age"`
}

然后在主代码和“进程”函数中使用这个结构。 这可行,但这似乎用 bson 标签“毒化”了主代码的 Result 结构。例如,如果后端结果是 XML 文件,该怎么办?我还必须将 xml 标签添加到结构中。或者也许有一天会标记一些非常模糊的数据库适配器。 在我看来,这似乎不是最干净的方法。我宁愿在主代码中有一个干净的 Result 结构,而只是从一个结构到另一个结构的转换。

是否有任何简单的方法可以做到这一点,或者我真的必须将 ResultBackend 结构的所有字段复制到新的 Result 结构并返回它?或者我想在这里过度简化我的代码? :)

干杯!

【问题讨论】:

  • 我当然建议将所有字段复制到一个新结构中,因为它不会有那些讨厌的注释。它会很好地完成您的应用程序。
  • 我当然是在讽刺。更重要的是什么;您的应用程序的性能还是您是否必须阅读编译器使用的一些文本?
  • 没有讽刺意味:性能,是的。而且我的代码的可读性和对(未来)后端服务的独立性。每当后端服务发生变化时,我更喜欢尽可能少地接触代码。正如我所说,这当然只适用于可以用标签序列化的结果。如果我使用一些不支持标签(或 json 或 XML 或 ...)的深奥后端,无论如何我都必须将这些字段复制到结构中,对吗?
  • 作为折衷方案,我建议在您的应用程序层中使用一个接口,并让不同的类型在数据划分的两端(客户端和数据库端)实现它。话虽如此,如果双方的模型相同为什么不使用相同的对象!?如果您的模型在后端更改为 XML,您只需找到 bson 并将其替换为xml,具有不同的结构不会使更改有任何不同。此外,添加多余的类型不会让你的程序更具可读性,它会让未来的开发者鄙视你。

标签: go


【解决方案1】:

如果您愿意,我会为每种“序列化格式”创建一个单独的类型。这种方法有几个优点:

  • 您的顾虑是分开的。

  • JSON un/marshalling 不会干扰 BSON/XML,因此您可以添加任何类型的附加结构字段(例如 xml.Name)。

  • 您实际上可以为需要不同参数的不同 API 创建多个此类类型。

我看到的唯一缺点是在它们之间移动数据需要更多代码甚至更多代码。最终取决于您和您的应用程序设计。如果您确定您的 JSON/BSON 将保持不变,您可以使用一种类型。否则,我会推荐专业。

【讨论】:

  • 是的,我想这是两全其美的做法,我尝试了这种方法。干杯!
【解决方案2】:

对于那些想在 golang 结构中添加 bson 标签的人,这里有一个工具可以提供帮助。我花了一整天的时间寻找这个,我希望其他人节省他们宝贵的时间。

你可以转换以下结构

type Result struct {
    Name string `json:"name"`
    Age int `json:"age"`
}

进入

type Result struct {
    Name string `json:"name" bson:"fullName"`
    Age int `json:"age bson:"age"`
}

有了这个工具,你不仅可以添加bson标签,还可以

  • XML 标签,
  • 定义验证和范围
  • 格式化标签值
  • 应用转换
  • 跳过未导出的字段。

去修改标签: https://github.com/fatih/gomodifytags

干杯,

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-28
    • 2021-03-05
    • 2017-02-09
    • 2019-10-07
    • 2020-11-22
    • 2018-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多