如何使用go代码动态创建结构及其属性?

时间:2018-04-13 15:50:06

标签: go

我是golang的新手 如何从gocode动态创建结构和属性, 它必须最终将它存储为文件。

例如:

结构名称:user 默认情况下,它必须创建Name属性

type User struct {
    Name string
}

它必须存储为文件ex: user_struct.go

你可以请某人帮忙找到办法吗

2 个答案:

答案 0 :(得分:2)

使用text/template编写Go代码。由于我不知道您希望如何详细地执行此操作,因此我将在示例中使用一个简单的模板。任何类型的真实世界模板都会产生格式错误的代码,但多亏了fmt,你几乎只需要让新行正确(如果你遇到麻烦,可以使用分号)。 go fmt在引擎盖下使用go/printer,你也可以。

有关详细信息,请参阅链接的包文档和示例。

package main

import (
    "bytes"
    "go/parser"
    "go/printer"
    "go/token"
    "html/template"
    "io"
    "log"
    "os"
)

var structTpl = `
    package main

    type {{ . }} struct {
            Name string
    }
    `

func main() {
    // Only do this once per template at the start of your program.
    // Then simply call Execute as necessary.
    tpl := template.Must(template.New("foo").Parse(structTpl))

    messy := &bytes.Buffer{}
    tpl.Execute(messy, "User")

    // Parse the code
    fset := &token.FileSet{}
    ast, err := parser.ParseFile(fset, "", messy, parser.ParseComments|parser.DeclarationErrors)
    if err != nil {
        log.Fatal(err)
    }

    // Print the code, neatly formatted.
    neat := &bytes.Buffer{}
    err = printer.Fprint(neat, fset, ast)
    if err != nil {
        log.Fatal(err)
    }

    io.Copy(os.Stdout, neat) // Or write to file as desired.
}

在操场上试试:https://play.golang.org/p/YhPAeos4-ek

答案 1 :(得分:0)

如果您正在寻找有关结构,接收器等的基于ast的元信息,您可以考虑以下内容:

package main
import  "github.com/viant/toolbox"

func main() {

    goCodeLocation := ".."
    fileSetInfo, err := toolbox.NewFileSetInfo(goCodeLocation)
    if err != nil {
        panic(err)
    }
    toolbox.Dump(fileSetInfo)
}