
在 go 的 `html/template` 中,可通过 `index` 函数结合嵌套 `range` 实现对平行数组或二维切片的逐层遍历——外层用 `$i, $e := .title` 获取索引与元素,内层用 `{{range index $.article $i}}` 遍历对应位置的子数组。
Go 模板本身不支持直接对“索引结果”再次执行 range(例如 {{range index $.Article $i}} 中的 index 返回的是 []string,需显式开启新循环),但完全支持嵌套 range ——这是处理多维数据结构的标准方式。
以下是一个完整、可运行的示例,展示如何渲染一个包含标题列表([]string)和对应文章段落列表([][]string)的结构:
package main
import (
"html/template"
"os"
)
type PageData struct {
Title []string
Article [][]string
}
func main() {
data := &PageData{
Title: []string{"简介", "安装", "使用指南"},
Article: [][]string{
{"Go 是一门静态类型、编译型语言。", "设计初衷是解决大规模工程中的效率与可维护性问题。"},
{"下载二进制包并解压。", "将 `bin/` 加入 PATH。", "运行 `go version` 验证。"},
{"定义模板字符串。", "调用 `template.Parse()`。", "传入数据执行 `Execute()`。"},
},
}
tmpl := `
{{range $i, $title := .Title}}
<h2>{{ $title }}</h2>
<ul>
{{range $para := index $.Article $i}}
<li>{{ $para }}</li>
{{end}}
</ul>
{{end}}
`
t := template.Must(template.New("page").Parse(tmpl))
t.Execute(os.Stdout, data)
}输出 HTML 片段如下:
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
<h2>简介</h2>
<ul>
<li>Go 是一门静态类型、编译型语言。</li>
<li>设计初衷是解决大规模工程中的效率与可维护性问题。</li>
</ul>
<h2>安装</h2>
<ul>
<li>下载二进制包并解压。</li>
<li>将 `bin/` 加入 PATH。</li>
<li>运行 `go version` 验证。</li>
</ul>
<h2>使用指南</h2>
<ul>
<li>定义模板字符串。</li>
<li>调用 `template.Parse()`。</li>
<li>传入数据执行 `Execute()`。</li>
</ul>⚠️ 注意事项:
- index $.Article $i 必须确保 $i 在 $.Article 切片长度范围内,否则模板执行会 panic(如 index out of range)。生产环境建议提前校验数据一致性,或在模板中配合 if 判断(例如 {{if lt $i (len $.Article)}}...{{end}});
- 模板内变量作用域受 range 影响:内层 range 会覆盖外层同名变量(如 $i),因此推荐为内层迭代变量命名(如 $para),避免歧义;
- 若需同时访问子数组的索引(如 0, 1, 2),可在内层使用 {{range $j, $para := index $.Article $i}},实现双层索引控制。
总结:Go 模板虽无原生“多维 range”,但通过 index + 嵌套 range 的组合,足以清晰、安全地处理平行数组、二维切片等常见数据结构,关键在于理解 index 返回值的类型,并为其匹配合适的迭代语法。

















