go - 通过读取 .go 文件来反射(reflection)结构类型

标签 go reflection code-generation introspection

我正在探索生成器 (go generate) 并尝试为我的结构生成验证函数。

我的想法是我不希望我的程序在运行时使用反射,我宁愿让生成器使用反射来生成我想要使用的实际方法。

问题是我无法在生成器代码中导入我的结构,到目前为止我发现的唯一方法是从生成器读取 .go 文件并使用正则表达式手动解析那里定义的类型

我有类似的东西

模型/模型.go:

package models

//go:generate go run ../generator.go -file models.go

type MyStruct struct {
    ...
}

generator.go:

package main

func main() {
    f, err := ioutil.ReadFile(fileName) // I read filename from the flag provided
    ...
    // I parse f to generate my stuff
}

我非常希望有一个内省(introspection)包,它将一个 go 代码作为一个字符串,并给我一些关于在那里定义的结构的信息

或者也许有一种方法可以导入调用 go:generate 的文件以直接访问类型

最佳答案

不需要指定文件名,这段代码也是一样的:

//go:generate go run ../generator.go -file $GOFILE

在 text/template 包的帮助下,您无需解析文件。一个非常简单的例子就是这样。这会给你线索:

package main

import (
    "flag"
    "os"
    "text/template"
)

//go:generate go run main.go -name=A
//go:generate go run main.go -name=B
//go:generate go run main.go -name=C

var name = flag.String("name", "test", "name of struct")

var code = `
package main

type Struct{{.}} struct {}

func (s *Struct{{.}} ) Vailadte() bool {
return true
}
`

func main() {
    flag.Parse()
    file, _ := os.Create(*name + ".go")
    defer file.Close()

    tmpl, _ := template.New("test").Parse(code)
    tmpl.Execute(file, *name)
}

关于go - 通过读取 .go 文件来反射(reflection)结构类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53782952/

相关文章:

templates - 如何将变量传递给模板并在 beego 中接收变量

c# - 如何搜索各种类型的属性

c# - 使用 Visual Studio 建模项目创建 C# 事件

python - Ruby/Python - 生成和解析 C/C++ 代码

date - 如何格式化持续时间

go - 您是否应该使用零 "enum"值来指示无效值

c# - 根据属性值在 C# 中查找函数

java - IntelliJ IDEA有Create Wrapper代码生成器吗

go - 插件是使用其他版本的软件包构建的

java - 如何利用反射满足工厂模式中的开闭原则?