
在Go模板中,当通过Execute传入切片作为数据源时,模板上下文中的点号(.)即代表该切片本身,而非结构体字段;因此应直接用{{range .}}遍历,而非错误地写成{{range .Files}}。
在go模板中,当通过execute传入切片作为数据源时,模板上下文中的点号(.)即代表该切片本身,而非结构体字段;因此应直接用`{{range .}}`遍历,而非错误地写成`{{range .files}}`。
Go模板引擎的执行上下文以“管道(pipeline)”为核心,而初始管道值(即.)完全由Execute方法传入的数据决定。在您的代码中:
err = t.Execute(os.Stdout, Files) // Files 是 []File 类型
此时模板内的.就等价于整个[]File切片,它没有名为Files的字段——这正是报错 can't evaluate field Files in type []main.File 的根本原因。
✅ 正确做法是:直接对.进行range遍历,每次迭代中.将自动绑定为当前元素(即单个File结构体):
const tmpl = `
{{range .}}
file name: {{.FileName}}, size: {{.FileSize}}
{{end}}
`
完整可运行示例:
package main
import (
"os"
"text/template"
)
type File struct {
FileName string
FileSize int64
}
func main() {
Files := []File{
{"data.txt", 123},
{"prog.go", 5678},
{"config.json", 987},
}
const tmpl = `
{{range .}}
file name: {{.FileName}}, size: {{.FileSize}} bytes
{{end}}
`
t := template.Must(template.New("filelist").Parse(tmpl))
if err := t.Execute(os.Stdout, Files); err != nil {
panic(err)
}
}
输出结果:
file name: data.txt, size: 123 bytes
file name: prog.go, size: 5678 bytes
file name: config.json, size: 987 bytes
⚠️ 注意事项:
- 若需在模板中同时访问切片长度、索引或嵌套数据,可结合$(根上下文)、$index(range $index, $value := .)或len .等内置函数;
- 避免混淆:.Files仅在传入的是包含Files字段的结构体(如struct{ Files []File })时才合法;
- 模板调试建议:开启template.FuncMap添加调试函数,或使用{{printf "%#v" .}}临时查看当前.值。
掌握.的生命周期与作用域,是写出健壮Go模板的关键基础。











