
在Go模板中,range遍历切片时需直接使用.引用传入的切片本身,而非误写为.FieldName;因为Execute传入的是切片值,此时.即代表该切片,其元素才是结构体实例。
在go模板中,`range`遍历切片时需直接使用`.`引用传入的切片本身,而非误写为`.fieldname`;因为`execute`传入的是切片值,此时`.`即代表该切片,其元素才是结构体实例。
Go模板引擎中,.(称为“dot”)始终代表当前作用域下的数据上下文。当你调用 t.Execute(os.Stdout, Files) 时,Files(类型为 []File)直接成为模板执行的根上下文,即 . 的初始值就是这个切片——不是包含该切片的某个结构体,因此 .Files 会报错:“can't evaluate field Files in type []main.File”。
正确做法是:在 {{range .}} 中,. 即为切片本身,range 会自动将每次迭代的当前元素赋给新的 .。因此模板应简化为:
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", 2048},
}
const tmpl = `
{{range .}}
file name: {{.FileName}}, size: {{.FileSize}} bytes
{{end}}
`
t := template.Must(template.New("list").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: 2048 bytes
⚠️ 注意事项:
- 若需访问嵌套字段(如 File 的 FileName),必须确保字段名首字母大写(导出),否则模板无法访问;
- 不要试图在切片上下文中写 {{.Files}}——除非你传入的是一个包含 Files 字段的结构体(例如 struct{ Files []File }),此时才适用 {{range .Files}};
- 模板中 {{.}} 在 range 内部指代当前元素(即单个 File),在 range 外部则指代整个切片。
掌握 . 的作用域变化,是写出健壮 Go 模板的关键基础。











