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

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

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

问题

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

以下是我目前的示例:

package models

type User struct {
	Email      string  `json:"email" binding:"email"`
	FirstName  string `json:"firstName" binding:"required"`
}

如何获取字段及其类型:

cfg := &packages.Config{
	Mode: packages.NeedName | packages.NeedFiles | packages.NeedSyntax | packages.NeedTypes | packages.NeedTypesInfo,
}
pkgs, _ := packages.Load(cfg, "./models")
pkg := pkgs[0]

structInfo := pkg.Types.Scope().Lookup("User").Type().Underlying().(*types.Struct)
for i := 0; i < structInfo.NumFields(); i++ {
	field := structInfo.Field(i)
	fieldType := field.Type()
	print("Field: ", field.Name(), " Type: ", fieldType.String())
}

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

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:

package models

type User struct {
	Email      string  `json:&quot;email&quot; binding:&quot;email&quot;`
	FirstName  string `json:&quot;firstName&quot; binding:&quot;required&quot;`
}

How I get the fields and their types:

cfg := &amp;packages.Config{
		Mode: packages.NeedName | packages.NeedFiles | packages.NeedSyntax | packages.NeedTypes | packages.NeedTypesInfo,
	}
	pkgs, _ := packages.Load(cfg, &quot;./models&quot;)
	pkg := pkgs[0]

	structInfo := pkg.Types.Scope().Lookup(&quot;User&quot;).Type().Underlying().(*types.Struct)
	for i := 0; i &lt; structInfo.NumFields(); i++ {
		field := structInfo.Field(i)
		fieldType := field.Type()
		print(&quot;Field: &quot;, field.Name(), &quot; Type: &quot;, fieldType.String())
	}

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

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作为辅助类型来解析原始标签字符串中的各个标签值。

tag := structInfo.Tag(i) // 获取原始未解析的标签字符串
stag := reflect.StructTag(tag) // 转换为reflect.StructTag类型
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.

tag := structInfo.Tag(i) // get the raw unparsed tag string
stag := reflect.StructTag(tag) // convert to reflect.StructTag
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:

确定