在使用 Go 语言的 text/template 包时,格式化嵌套数据结构往往会产生许多不希望出现的空行。由于 Go 模板会保留所有空白字符——包括用于排版模板代码本身的换行符——标准的循环写法很容易产生充斥着空行的臃肿输出。
下面介绍如何利用 Go 模板的空白裁剪标记(trim markers)来解决空白字符问题。
假设我们想要格式化下面这个嵌套数据结构:
var data = map[string]map[string][]string{
"1": {
"1.1": {"1.1.1", "1.1.2", "1.1.3"},
},
"2": {
"2.1": {"2.1.1", "2.1.2", "2.1.3"},
},
}
编写模板时,一种很自然的写法是使用标准的 {{ range }} 块:
{{ range $name, $map := . }}
{{ $name }}:
{{ range $name, $values := $map }}
{{ $name }}:
{{ range $value := $values }}
{{ $value }}
{{ end }}
{{ end }}
{{ end }}
因为模板中的每一个换行符和缩进空格都会按原样输出,最终的打印结果会充斥着大量多余的空行:
1:
1.1:
1.1.1
1.1.2
1.1.3
2:
...
-)
🔗我们可以在模板动作标签内部添加减号(-),指示 Go 模板引擎吞掉相邻的空白字符:
{{- ... }} 会移除前面所有的前导空白字符(空格、制表符和换行符),直到遇到前一个非空白字符为止。{{ ... -}} 会移除后面所有的尾随空白字符,直到遇到下一个非空白字符为止。为了修复我们的嵌套循环,我们可以有策略地放置 - 标记,吞掉用于模板排版的换行符,同时保留我们想要的缩进空格:
{{- range $name, $map := . -}}
{{ $name }}:
{{- range $name, $values := $map }}
{{ $name }}:
{{- range $value := $values }}
{{ $value }}
{{- end }}
{{- end }}
{{ end -}}
通过剔除紧跟在 range 声明和 end 块前后的换行符,我们就能得到干净、紧凑的输出结果:
1:
1.1:
1.1.1
1.1.2
1.1.3
2:
2.1:
2.1.1
2.1.2
2.1.3
你可以复制并运行以下代码,直接测试其实际效果。
package main
import (
"fmt"
"os"
"text/template"
)
var data = map[string]map[string][]string{
"1": {
"1.1": {"1.1.1", "1.1.2", "1.1.3"},
},
"2": {
"2.1": {"2.1.1", "2.1.2", "2.1.3"},
},
}
func main() {
const tpl = `
{{- range $name, $map := . -}}
{{ $name }}:
{{- range $name, $values := $map }}
{{ $name }}:
{{- range $value := $values }}
{{ $value }}
{{- end }}
{{- end }}
{{ end -}}
`
fmt.Println("Output:")
fmt.Println("'''")
t := template.Must(template.New("nested").Parse(tpl))
t.Execute(os.Stdout, data)
fmt.Println("'''")
}
获取《卡乌埃的生活方式》精选离线版——一份全面优化 🍏 健康、💰 财富、❤️ 爱 与 🧘 意义 的实践指南。
当我发布关于美好生活的新随笔、读书笔记和实践指南时接收通知。绝无垃圾邮件——可随时退订。
有任何问题、见解或建议吗?欢迎在下方分享您的想法。评论功能由 GitHub Discussions 驱动(无广告、无垃圾信息)——点击下方的使用 GitHub 登录即可发表评论或互动(注册免费 GitHub 账号不到一分钟即可完成)。
最后更新于 2026年10月11日.
免责声明:本站所有内容仅供信息参考与教育用途,不构成任何医疗、心理、财务、投资、税务或法律建议。此处呈现的观点、整理与见解仅代表我个人,不代表我雇主的立场。书籍、演讲及文章摘要均为独立的教育性评论,其知识产权归原作者所有。本站可能使用 AI 工具辅助编辑、排版与归纳;尽管我们竭力确保准确无误,但仍可能存在疏漏。隐私政策:本站使用第三方服务提供可选的邮件通讯订阅(follow.it)、评论(giscus / GitHub Discussions)以及嵌入媒体(YouTube),这些服务可能会依据各自的隐私政策处理访客的 IP 地址和 Cookie。