Function 在Go模板中,我可以让Parse工作,但不能让parsefile以类似的方式工作。为什么?

Function 在Go模板中,我可以让Parse工作,但不能让parsefile以类似的方式工作。为什么?,function,parsing,templates,go,Function,Parsing,Templates,Go,我有以下代码: t, err := template.New("template").Funcs(funcMap).Parse("Howdy {{ myfunc . }}") 在这种形式下,一切正常。但是,如果我对ParseFile执行完全相同的操作,那么将上面的文本放在template.html中是不可能的: t, err := template.New("template").Funcs(funcMap).ParseFiles("template.html") 我能够使ParseFile

我有以下代码:

t, err := template.New("template").Funcs(funcMap).Parse("Howdy {{ myfunc . }}")
在这种形式下,一切正常。但是,如果我对ParseFile执行完全相同的操作,那么将上面的文本放在
template.html
中是不可能的:

t, err := template.New("template").Funcs(funcMap).ParseFiles("template.html")
我能够使ParseFile以以下形式工作,但无法使Funcs生效:

t, err := template.ParseFiles("template.html")
t.Funcs(funcMap)
当然,最后一种形式是对函数的直接调用,而不是对receiver方法的调用,因此不同


有人知道这是怎么回事吗?很难在中找到关于模板的详细信息。

ParseFiles
应该有一些模板的名称,即文件名的basename。但是您调用
template.New
,它将创建名为
error
的模板的新模板。所以你应该选择一个模板

foo.go foo.tmpl
对源代码中的
template.ParseFiles
进行了一些挖掘并找到了此注释:

如果尚未定义,第一个模板将成为返回值,我们将在后续的新调用中使用该模板将所有模板关联在一起。另外,如果此文件与t同名,则此文件将成为t的内容,因此t,err:=New(name).Funcs(xxx).ParseFiles(name)工作。否则,我们将创建一个与t关联的新模板

因此,根据我上面的示例,格式应如下所示:

t, err := template.New("template.html").Funcs(funcMap).ParseFiles("path/template.html")
.New(“template.html”)
创建一个具有给定名称的空模板,
.Funcs(funcMap)
将要应用于模板的任何自定义函数关联起来,然后
.ParseFiles(“path/template.html”)
解析一个或多个模板,了解这些函数,并将内容与该名称的模板关联

请注意,第一个文件的基本名称必须与
New
中使用的名称相同。任何解析的内容都将与先前存在的空模板(与系列中的第一个文件具有相同的基名称)或具有该基名称的新模板相关联

因此,在我上面的示例中,创建了一个名为“template”的空模板,并与之关联了一个函数映射。然后创建了一个名为“template.html”的新模板这些不一样由于,
ParseFiles
是最后调用的,
t
最终成为“template.html”模板,没有附加任何函数

最后一个例子呢?为什么这不起作用?调用receiver方法,该方法反过来应用任何以前注册的函数:

trees, err := parse.Parse(t.name, text, t.leftDelim, t.rightDelim, t.parseFuncs, builtins)
这意味着在解析之前必须注册自定义函数。解析模板后添加函数不会产生任何影响,在尝试调用自定义函数时会导致运行时出现零指针错误

所以我认为这涵盖了我最初的问题。这里的设计似乎有点笨重。如果我可以将
ParseFiles
链接到一个模板,然后返回一个与我链接的模板不同的模板(如果它们的名称不一致),这是没有意义的。这是违反直觉的,可能应该在未来的版本中解决,以避免混淆。

尝试以下方法:

var templates = template.Must(template.New("").Funcs(fmap).ParseFiles("1.tmpl, "2.tmpl"))

ParseFile是否有任何错误?我们是否可以假设您正在将其添加到现有的*template.template中,因为您正在使用赋值运算符?是否检查了错误?是否进行了一些调查并发现了错误。模板名称必须与第一个文件的名称相同。如果你问我的话,这有点奇怪。
trees, err := parse.Parse(t.name, text, t.leftDelim, t.rightDelim, t.parseFuncs, builtins)
var templates = template.Must(template.New("").Funcs(fmap).ParseFiles("1.tmpl, "2.tmpl"))