Go结构体字段的标签转换

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

Conversion of Go struct fields with tags

问题

我在Go语言中遇到了一个看似微不足道的问题,真的被卡住了:
我有一个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
    ... 在这里执行MongoDB查询并将结果存储在result变量中 ...
    return result
}

这当然行不通,因为我们有两个不同的结构体。
当然,一种解决方法是将两个标签嵌入一个结构体中,像这样:

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

然后在主代码和"process"函数中使用这个结构体。
这样可以工作,但在我看来,这似乎是在主代码中"污染"了Result结构体。例如,如果后端结果是一个XML文件,我还需要在结构体中添加XML标签。或者也许将来会有一些非常奇怪的数据库适配器需要添加标签。
在我看来,这不是最干净的方法。我宁愿在主代码中有一个干净的Result结构体,然后简单地将一个结构体转换为另一个结构体。

有没有简单的方法可以做到这一点,或者我真的必须将ResultBackend结构体的所有字段复制到一个新的Result结构体中并返回呢?或者我在这里试图过度简化我的代码? Go结构体字段的标签转换

祝好!

英文:

I am really stuck here with a seemingly trivial problem in Go:
I have a Golang microservice, which outputs data in json format. Let's say I have a simple struct with json tags for this result:

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

In the code part where the data is actually pulled out of the database, I have a quite similar struct, like this:

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

The struct fields are similar, except the different tags. I would like to keep things simple, and return just one struct from the backend service (ResultBackend), which can then be send as a JSON response, like this:

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

This certainly would not work, because we have two different structs here.
Of course one solution would be to embed both tags in one struct like so:

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

and then use this struct in the main code and the "process" function.
This works, but this seems like "poisoning" the Result struct of the main code with the bson tags. What, for instance, if the backend result is a XML file? I'd have to add xml tags to the struct as well. Or maybe someday tags some very obsure database adapter.
This doesn't seem to be the cleanest approach in my eyes. I'd rather have a clean Result struct in the main code, and simply to a conversion from one struct to another.

Is there any easy way doing that, or do I really have to copy all the fields of a ResultBackend struct to a new Result struct and return that? Or I am trying to over-simplify my code here? Go结构体字段的标签转换

Cheers!

答案1

得分: 2

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

  • 您的关注点被分离开来。

  • JSON 的序列化和反序列化不会干扰 BSON/XML,因此您可以添加任何类型的额外结构字段(例如 xml.Name)。

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

我唯一看到的缺点是这会增加更多的代码,并且在这些类型之间移动数据也需要更多的代码。最终,这取决于您和您的应用程序设计。如果您确定您的 JSON/BSON 将保持不变,您可以使用一个类型。否则,我建议进行专门化处理。

英文:

What I'd do is create a separate type for every "serialisation format" if you will. This approach has several advantages:

  • Your concerns are separated.

  • JSON un/marshalling doesn't interfere with BSON/XML, so you can add any kind of additional struct fields (like xml.Name for example).

  • You can actually create several such types for different APIs that need different parameters.

The only disadvantage I see is that it's more code and even more code to move data between those. Ultimately it's up to you and your application design. If you're sure that your JSON/BSON will stay the same, you can use one type. Otherwise, I'd recommend specialisation.

答案2

得分: 0

对于那些想在Go语言结构体中添加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标签
  • 定义验证和范围
  • 格式化标签值
  • 应用转换
  • 跳过未导出的字段

Go Modify Tags: https://github.com/fatih/gomodifytags

祝好!

英文:

To those who want to add bson tags in golang struct, here is a tool which can be helpful. I have spent a whole day searching for this and I want others to save their valuable time.

You can convert the following struct

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

into

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

With this tool, you can not only add bson tags but also

  • XML tags,
  • Define validation and scope
  • Format tag values
  • Apply transformation
  • skip unexported fields.

Go Modify Tags: https://github.com/fatih/gomodifytags

Cheers,

huangapple
  • 本文由 发表于 2015年8月3日 23:22:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/31791045.html
匿名

发表评论

匿名网友

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

确定