Goの text/template パッケージを扱う際、ネストされたデータ構造をフォーマットしようとすると、意図しない空行が大量に出力されてしまうことがよくあります。Goのテンプレートは、テンプレートコード自体の整形に使われた改行を含め、すべての空白文字(ホワイトスペース)をそのまま保持するため、通常のループ処理では出力が間延びしてしまうのです。
ここでは、Goテンプレートの「トリムマーカー」を使ってこの空白問題を解決する方法を紹介します。
たとえば、次のようなネストされたデータ構造をフォーマットしたいとします。
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 アカウントは1分未満で作成できます)。
最終更新日: 2026/10/11.
免責事項:当サイトのコンテンツは情報提供および教育のみを目的としており、医療、心理、金融、投資、税務、または法律上の助言を構成するものではありません。ここに掲載されている考え、キュレーション、意見はすべて私個人のものであり、雇用主の見解を代表するものではありません。書籍、講演、記事の要約は独立した教育的な解説であり、それぞれの著者の知的財産です。編集、フォーマット、要約の補助としてAIツールを使用する場合がありますが、正確性を期すよう努めているものの誤りが含まれる可能性があります。プライバシー:当サイトでは、任意のニュースレター購読(follow.it)、コメント機能(giscus / GitHub Discussions)、および埋め込みメディア(YouTube)に外部サービスを利用しており、これらのサービスはそれぞれのプライバシーポリシーに従って訪問者のIPアドレスやCookieを処理する場合があります。