一尘不染

Golang模板(并将函子传递给模板)

go

尝试访问传递给模板的函数时出现错误:

Error: template: struct.tpl:3: function "makeGoName" not defined

有人可以让我知道我在做什么错吗?

模板文件(struct.tpl):

type {{.data.tableName}} struct {
  {{range $key, $value := .data.tableData}}
  {{makeGoName $value.colName}} {{$value.colType}} `db:"{{makeDBName $value.dbColName}},json:"{{$value.dbColName}}"`
  {{end}}
}

调用文件:

type tplData struct {
    tableName string
    tableData interface{}
}

func doStuff() {
    t, err := template.ParseFiles("templates/struct.tpl")
    if err != nil {
        errorQuit(err)
    }

    t = t.Funcs(template.FuncMap{
        "makeGoName": makeGoName,
        "makeDBName": makeDBName,
    })

    data := tplData{
        tableName: tableName,
        tableData: tableInfo,
    }

    t.Execute(os.Stdout, data)
}

func makeGoName(name string) string {
    return name
}

func makeDBName(name string) string {
    return name
}

这是用于生成struct样板代码的程序(以防万一有人想知道为什么我要在模板中这样做)。


阅读 206

收藏
2020-07-02

共1个答案

一尘不染

自定义函数需要在解析模板之前进行注册,否则解析器将无法分辨标识符是否为有效的函数名。模板被设计为可静态分析的,这是必需的。

您可以先使用创建一个新的未定义模板template.New(),并且除了
函数 之外,类型(由返回)还具有 方法
,您可以调用该方法。template.ParseFiles()
template.TemplateNew()Template.ParseFiles()

像这样:

t, err := template.New("").Funcs(template.FuncMap{
    "makeGoName": makeGoName,
    "makeDBName": makeDBName,
}).ParseFiles("templates/struct.tpl")

请注意,该template.ParseFiles()函数还会template.New()在后台调用,将第一个文件的名称作为模板名称传递。

Template.Execute()返回error,打印以查看是否未生成任何输出,例如:

if err := t.Execute(os.Stdout, data); err != nil {
    fmt.Println(err)
}
2020-07-02