简体   繁体   English

通过读取 a.go 文件反映结构类型

[英]Reflect on struct type from reading a .go file

I'm discovering generator (go generate) and I'm trying to generate Validation function for my struct.我正在发现生成器(go generate),并且正在尝试为我的结构生成验证 function。

The idea is that I don't want my program to use reflect at runtime, I would rather have a generator use reflect to generate the actual method I want to use.这个想法是我不希望我的程序在运行时使用反射,我宁愿让生成器使用反射来生成我想要使用的实际方法。

the problem is I can't import my structs in the generator code, the only way I found so far was to read the.go file from the generator and manually parse the types defined there using regex问题是我无法在生成器代码中导入我的结构,到目前为止我发现的唯一方法是从生成器中读取 .go 文件并使用正则表达式手动解析那里定义的类型

I've got something like我有类似的东西

models/models.go:型号/型号.go:

package models

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

type MyStruct struct {
    ...
}

generator.go:发电机.go:

package main

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

I would very much prefer to have an introspection package that would take a go code as a string and give me some information about the struct defined there我非常希望有一个自省 package 将 go 代码作为字符串并给我一些关于那里定义的结构的信息

Or maybe there is a way to import the file that call go:generate to get directly access to the types或者也许有一种方法可以导入调用 go:generate 的文件以直接访问类型

There is no need to specify file name , this code does the same : 无需指定文件名,此代码也是如此:

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

With help of text/template package you are needless of parsing the file. 在文本/模板包的帮助下,您无需解析文件。 A very simple example would be something like this. 一个非常简单的例子就是这样的。 This will give you the clue : 这将为您提供线索:

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)
}

Maybe you can utilize go/parser and go/ast in your generator.也许你可以在你的生成器中使用go/parsergo/ast

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM