ParseFiles
是一个独立的(standalone)函数,它可以对模板文件进行语法分析,并创建出一个经过语法分析的模板结构以供Execute
方法执行。
实际上,ParseFiles
函数只是为了方便地调用Template
结构的ParseFiles
方法而设置的一个函数——当用户调用ParseFiles
函数的时候,Go会创建一个新的模板,并将用户给定的模板文件的名字用作这个新模板的名字:
t, _ := template.ParseFiles("tmpl.html")
这相当于创建一个新模板,然后调用它的ParseFiles
方法:
t := template.New("tmpl.html")
t, _ := t.ParseFiles("tmpl.html")
无论是ParseFiles
函数还是Template
结构的ParseFiles
方法,它们都可以接受一个或多个文件名作为参数,换句话说,这两个函数/方法都是可变参数函数/方法,它们可以接受的参数数量是可变的。但与此同时,无论这两个函数/方法接受多少个文件名作为输入,它们都只返回一个模板。
当用户向ParseFiles
函数或ParseFiles
方法传入多个文件时,ParseFiles
只会返回用户传入的第一个文件的已分析模板,并且这个模板也会根据用户传入的第一个文件的名字进行命名;至于其他传入文件的已分析模板则会被放置到一个映射里面,这个映射可以在之后执行模板时使用。
换句话说,我们可以这样认为:在向ParseFiles
传入单个文件时,ParseFiles
返回的是一个模板;而在向ParseFiles
传入多个文件时,ParseFiles
返回的则是一个模板集合,理解这一点能够帮助我们更好地学习本章稍后将要介绍的嵌套模板技术。
对模板文件进行语法分析的另一种方法是使用ParseGlob
函数,跟ParseFiles
只会对给定文件进行语法分析的做法不同,ParseGlob
会对匹配给定模式的所有文件进行语法分析。举个例子,如果目录里面只有tmpl.html
一个HTML文件,那么语句
t, _ := template.ParseFiles("tmpl.html")
和语句
t, _ := template.ParseGlob("*.html")
将产生相同的效果。
在绝大多数情况下,程序都是对模板文件进行语法分析,但是在需要时,程序也可以直接对字符串形式的模板进行语法分析。实际上,所有对模板进行语法分析的手段最终都需要调用Parse
方法来执行实际的语法分析操作。比如说,在模板内容相同的情况下,语句
t, _ := template.ParseFiles("tmpl.html")
和代码
tmpl := `<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Go Web Programming</title>
</head>
<body>
{{ . }}
</body>
</html>`
t := template.New("tmpl.html")
t, _ = t.Parse(tmpl)
t.Execute(w, "Hello World!")
将产生相同的效果。
到目前为止,本章一直都没有处理分析模板时可能会产生的错误。虽然Go语言的一般做法是手动地处理错误,但Go也提供了另外一种机制,专门用于处理分析模板时出现的错误:
t := template.Must(template.ParseFiles("tmpl.html"))
Must
函数可以包裹起一个函数,被包裹的函数会返回一个指向模板的指针和一个错误,如果这个错误不是nil
,那么Must
函数将产生一个panic
。(在Go里面,panic
会导致正常的执行流程被终止:如果panic
是在函数内部产生的,那么函数会将这个panic
返回给它的调用者。panic
会一直向调用栈的上方传递,直至main
函数为止,并且程序也会因此而崩溃。)