
本文详解如何在 Go 的 text/template 中正确遍历结构体切片([]struct),并通过模板语法访问每个结构体字段,附可运行示例与关键注意事项。
本文详解如何在 go 的 `text/template` 中正确遍历结构体切片(`[]struct`),并通过模板语法访问每个结构体字段,附可运行示例与关键注意事项。
在 Go Web 开发或命令行工具中,常需将结构体切片(如 []myType)传递给模板进行渲染。核心在于使用模板内置动作 range 配合变量绑定,而非直接调用 .ID 这类模糊表达式(因 . 在 range 内部会指向当前迭代项,但需显式声明才能安全访问嵌套字段)。
✅ 正确用法:range + 命名变量
Go 模板中推荐使用带索引和值命名的 range 语法:
{{range $index, $item := .}}
{{ $item.ID }} — {{ $item.Name }} — {{ $item.Test }}
{{end}}
其中 $index(可省略)接收循环索引,$item 接收当前结构体实例——必须通过 $item 显式引用字段,否则 . 在 range 内部即为当前结构体,但易与外层上下文混淆,降低可读性与可维护性。
? 完整可运行示例
package main
import (
"fmt"
"os"
"text/template"
)
type myType struct {
ID string
Name string
Test string
}
func main() {
list := []myType{
{"id1", "name1", "test1"},
{"id2", "name2", "test2"},
}
tmpl := `
| ID | Name | Test |
|---|---|---|
| {{ $item.ID }} | {{ $item.Name }} | {{ $item.Test }} |
✅ 输出为标准 HTML 表格,每行渲染一个 myType 实例的三个字段。
⚠️ 关键注意事项
- 字段必须导出(首字母大写):ID、Name、Test 是合法的;若定义为 id, name 则模板无法访问(Go 模板仅能访问导出字段)。
- 避免裸 . 访问:在 range 内直接写 {{.ID}} 虽然可行(因 . 此时即为当前结构体),但一旦嵌套多层 range 或逻辑复杂,极易出错。显式命名(如 $item)显著提升健壮性与可读性。
- 空切片安全:range 在空切片上自动不执行任何迭代,无需额外判空。
- 传参必须是切片本身:调用 t.Execute(os.Stdout, list) 时,list 是 []myType 类型;若误传 &list(指针)或 *list,模板将无法正确解包结构体字段。
掌握 range 与命名变量的组合,是 Go 模板处理集合数据的基础能力。无论渲染 HTML、配置文件还是日志摘要,这一模式都通用可靠。











