Go模板本地变量未定义报错原因分析及解决方法
Go模板本地变量报错问题解决
问题场景
在Go中使用模板时遇到本地变量相关报错,最初误以为是变量声明写法错误,排查后发现是模板加载逻辑的问题。
模板文件(index.gohtml)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Go Template Demo</title> </head> <body> {{$wisdom := "42"}} <h1>The meaning of life is {{$wisdom}}</h1> </body> </html>
主程序代码(main.go)
package main import( "log" "os" "text/template" ) // 创建模板容器并加载所有模板 var tpl *template.Template func init() { tpl = template.Must(template.ParseGlob("templates/**")) } func main() { // 输出到标准输出 err := tpl.ExecuteTemplate(os.Stdout, "index.gohtml", nil) if err != nil { log.Fatalln(err) } }
执行报错信息
> go run main.go panic: template: .index.gohtml.swp:1: undefined variable "$wisdom" goroutine 1 [running]: text/template.Must(...) /usr/local/go/src/text/template/helper.go:26 main.init.0() <home-path>/dev/go/gosite/main.go:13 +0x65 exit status 2
排查与解决
最初怀疑是变量声明写法问题,尝试了{{ with $wisdom := "42" }}<h1>{{$wisdom}}</h1>{{end}}的写法,依然报错。
最终排查发现:template.ParseGlob("templates/**")的匹配模式会加载目录下所有文件,包括Vim生成的隐藏交换文件.index.gohtml.swp,这个交换文件中没有定义$wisdom变量,导致模板加载时触发报错。
将glob匹配模式修改为仅匹配.gohtml后缀的文件即可解决问题:
tpl = template.Must(template.ParseGlob("templates/*.gohtml"))
内容的提问来源于stack exchange,提问作者overbyte
相关产品推荐
相关产品推荐

