
本文详解如何在Go的text/template中正确遍历结构体切片(slice),并通过模板语法访问每个结构体字段,附可运行示例与关键注意事项。
本文详解如何在go的`text/template`中正确遍历结构体切片(slice),并通过模板语法访问每个结构体字段,附可运行示例与关键注意事项。
在Go模板中渲染结构体数组(即[]struct)时,核心在于使用range动作配合变量绑定,以逐项解构并安全访问字段。下面以一个典型场景为例展开说明。
✅ 正确声明与初始化结构体及切片
首先确保结构体字段全部导出(首字母大写),否则模板无法访问:
type MyType struct { // 注意:类型名首字母大写,保证导出
ID string
Name string
Test string
}
var list = []MyType{
{"id1", "name1", "test1"},
{"id2", "name2", "test2"},
}⚠️ 原问题中 Name 和 Test 字段未声明类型且为小写,属未导出字段——这会导致模板中 {{.Name}} 返回空值。务必补全类型并首字母大写。
✅ 模板中遍历结构体数组:range 的两种常用写法
方式一:仅需结构体值(推荐简洁场景)
{{range .}}
<tr>
<td>{{.ID}}</td>
<td>{{.Name}}</td>
<td>{{.Test}}</td>
</tr>
{{end}}此时 . 在每次迭代中代表当前 MyType 实例。
方式二:同时获取索引和值(适合需序号或条件判断)
{{range $index, $item := .}}
<tr>
<td>{{$index}}. {{$item.ID}}</td>
<td>{{$item.Name}}</td>
<td>{{$item.Test}}</td>
</tr>
{{end}}$index 是整数索引(从0开始),$item 是当前结构体实例,命名清晰利于维护。
✅ 完整可运行示例
package main
import (
"os"
"text/template"
)
type MyType struct {
ID string
Name string
Test string
}
func main() {
list := []MyType{
{"id1", "name1", "test1"},
{"id2", "name2", "test2"},
}
tmpl := `
<table border="1">
{{range $i, $v := .}}
<tr>
<td>{{printf "%d." $i}}{{ $v.ID }}</td>
<td>{{ $v.Name }}</td>
<td>{{ $v.Test }}</td>
</tr>
{{end}}
</table>
`
t := template.Must(template.New("list").Parse(tmpl))
t.Execute(os.Stdout, list) // 输出HTML表格
}运行后将生成标准HTML表格,每行对应一个结构体实例。
? 注意事项总结
- 字段必须导出:所有待模板访问的字段须为大写字母开头,且显式声明类型(如 Name string,不可省略)。
- 传入数据需为切片本身:调用 t.Execute(w, list) 时,list 是 []MyType 类型;若包裹在 map 或 struct 中,需调整模板路径(如 {{range .Data}})。
-
避免空指针 panic:若切片可能为 nil,建议在模板中加安全判断:
{{if .}}{{range .}}...{{end}}{{else}}<tr><td colspan="3">No data</td></tr>{{end}} - 性能提示:对大型切片,模板渲染是内存操作,无需额外优化;但应避免在模板内执行复杂逻辑——业务逻辑请前置到 Go 代码中处理。
掌握 range 与点号(.)作用域规则,即可高效、安全地渲染任意结构体数组,这是Go Web开发与CLI工具中模板渲染的基石技能。

















