How do I get the tags in a struct through packages/packages?

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

How do I get the tags in a struct through packages/packages?

问题

我想获取有关结构体的信息,以便在自定义Go生成器中使用。
通过使用packages/packages,我可以获取结构体的所有字段和它们的类型,但我无法弄清楚如何获取每个字段的标签。生成器不在与我尝试读取的结构体相同的代码库中运行,所以据我所知,我不能使用反射本身。

以下是我目前的示例:

  1. package models
  2. type User struct {
  3. Email string `json:"email" binding:"email"`
  4. FirstName string `json:"firstName" binding:"required"`
  5. }

如何获取字段及其类型:

  1. cfg := &packages.Config{
  2. Mode: packages.NeedName | packages.NeedFiles | packages.NeedSyntax | packages.NeedTypes | packages.NeedTypesInfo,
  3. }
  4. pkgs, _ := packages.Load(cfg, "./models")
  5. pkg := pkgs[0]
  6. structInfo := pkg.Types.Scope().Lookup("User").Type().Underlying().(*types.Struct)
  7. for i := 0; i < structInfo.NumFields(); i++ {
  8. field := structInfo.Field(i)
  9. fieldType := field.Type()
  10. print("Field: ", field.Name(), " Type: ", fieldType.String())
  11. }

在反射中,可以使用以下方式获取标签:

  1. fieldType.Tag().Get("json")

但在packages/packages的结果中似乎不可能。是否有办法获取标签呢?

英文:

I want to fetch information about a struct to use in a custom go generator.
By using packages/packages I am able to fetch all fields from a struct and their types, I however can't figure out how to also fetch the tags for each field. The generator doesn't run in the same code base as the struct I try to read, so for as far as I know, I can't use reflection itself.

Example of what I have so far:

  1. package models
  2. type User struct {
  3. Email string `json:&quot;email&quot; binding:&quot;email&quot;`
  4. FirstName string `json:&quot;firstName&quot; binding:&quot;required&quot;`
  5. }

How I get the fields and their types:

  1. cfg := &amp;packages.Config{
  2. Mode: packages.NeedName | packages.NeedFiles | packages.NeedSyntax | packages.NeedTypes | packages.NeedTypesInfo,
  3. }
  4. pkgs, _ := packages.Load(cfg, &quot;./models&quot;)
  5. pkg := pkgs[0]
  6. structInfo := pkg.Types.Scope().Lookup(&quot;User&quot;).Type().Underlying().(*types.Struct)
  7. for i := 0; i &lt; structInfo.NumFields(); i++ {
  8. field := structInfo.Field(i)
  9. fieldType := field.Type()
  10. print(&quot;Field: &quot;, field.Name(), &quot; Type: &quot;, fieldType.String())
  11. }

In reflect there is the possibility to get the Tag by using

  1. fieldType.Tag().Get(&quot;json&quot;)

But this doesn't seem possible in results from packages/packages.
Is there a way to get the tags anyway?

答案1

得分: 1

使用Tag方法。你还可以使用reflect.StructTag作为辅助类型来解析原始标签字符串中的各个标签值。

  1. tag := structInfo.Tag(i) // 获取原始未解析的标签字符串
  2. stag := reflect.StructTag(tag) // 转换为reflect.StructTag类型
  3. stag.Get("json") // 从标签中获取值

https://go.dev/play/p/INpOyL9rS_f

英文:

Use the Tag method. And you can also use reflect.StructTag as a helper type to parse the individual tag values from the raw tag string.

  1. tag := structInfo.Tag(i) // get the raw unparsed tag string
  2. stag := reflect.StructTag(tag) // convert to reflect.StructTag
  3. stag.Get(&quot;json&quot;) // get values from the tag

https://go.dev/play/p/INpOyL9rS_f

huangapple
  • 本文由 发表于 2023年3月15日 19:25:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/75744055.html
匿名

发表评论

匿名网友

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

确定