Golang模板(并将func传递给模板)

时间:2016-02-22 09:45:09

标签: templates go go-templates

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

class Program
{
    static void Main(string[] args)
    {
        var watcher = new System.IO.FileSystemWatcher()
        {
            Path =  @"G:\cc\",
        };

        watcher.Created += Watcher_Created;
        watcher.EnableRaisingEvents = true;

        Console.ReadKey();
    }

    private static void Watcher_Created(
        object sender, 
        FileSystemEventArgs e
        )
    {
        var folder = new DirectoryInfo(e.FullPath)
            .Parent;

        Console.WriteLine(
            folder?
                .GetFiles()
                .Length
            );
    }
}

任何人都可以让我知道我做错了什么吗?

模板文件(struct.tpl):

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

调用文件:

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

这是一个生成结构样板代码的程序(如果有人想知道为什么我在我的模板中这样做)。

2 个答案:

答案 0 :(得分:8)

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

您可以先使用template.New()创建一个新的未定义模板,除了template.ParseFiles() 函数之外,还可以使用template.Template类型(New()返回})还有一个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)
}

答案 1 :(得分:1)

在为模板注册自定义功能并使用ParseFiles()时,需要在实例化并执行模板时指定模板的名称。致电ParseFiles()后,还需要致电Funcs()

// Create a named template with custom functions
t, err := template.New("struct.tpl").Funcs(template.FuncMap{
    "makeGoName": makeGoName,
    "makeDBName": makeDBName,
}).ParseFiles("templates/struct.tpl") // Parse the template file
if err != nil {
    errorQuit(err)
}

// Execute the named template
err = t.ExecuteTemplate(os.Stdout, "struct.tpl", data)
if err != nil {
    errorQuit(err)
}

使用命名模板时,名称是没有目录路径的文件名,例如struct.tpl不是templates/struct.tpl。因此,New()ExecuteTemplate()中的名称应为字符串struct.tpl