Go のテンプレートエンジンは、一般的なテンプレートエンジンの記法と気色が異なり、独特の文法で記述するのですが、ループ制御構文に関してはお世辞にも満足できる物ではありませんでした。それは continue や break が無いというのが理由です。continue や break が無かったので、無駄に if をネストして条件にあった値を出力しなければならず、必然的に無駄な if のネストが起きていました。
■ビーフストロガノフ
2011年 受賞
2019年 受賞
■カレーライス
2012年 受賞
■満漢全席
2015年 受賞
2019年 受賞
例えば上記の様な出力をするには、以下の様なテンプレートを書かなければなりませんでした。
package main
import (
"os"
"text/template"
)
var tmpl = `
{{- range .}}
{{- if gt .Value 3 -}}
■{{.Name}}
{{- range .Years }}
{{ . -}}年 受賞
{{- end}}
{{end -}}
{{- end -}}
`
type Foo struct {
Name string
Value int
Years []int
}
func main() {
tpl := template.Must(template.New("").Parse(tmpl))
tpl.Execute(os.Stdout, []Foo{
{Name: "ぶどう", Value: 1, Years: []int{2011, 2014, 2019}},
{Name: "みかん", Value: 2, Years: []int{2011}},
{Name: "ぎょうざ", Value: 3, Years: []int{2020}},
{Name: "ビーフストロガノフ", Value: 4, Years: []int{2011, 2019}},
{Name: "カレーライス", Value: 5, Years: []int{2012}},
{Name: "満漢全席", Value: 6, Years: []int{2015, 2019}},
})
}
html/template, text/template: implement break and continue for range … · golang/go@d0dd26a · GitHub
…loops Break and continue for range loops was accepted as a proposal in June 2017. It was implemente...
https://github.com/golang/go/commit/d0dd26a88c019d54f22463daae81e785f5867565
continue を使える様になった事で、ループのネストが下げられる様になりました。
package main
import (
"os"
"text/template"
)
var tmpl = `
{{- range .}}
{{- if le .Value 3 -}}{{continue}}{{end -}}
■{{.Name}}
{{- range .Years }}
{{ . -}}年 受賞
{{- end}}
{{end -}}
`
type Foo struct {
Name string
Value int
Years []int
}
func main() {
tpl := template.Must(template.New("").Parse(tmpl))
tpl.Execute(os.Stdout, []Foo{
{Name: "ぶどう", Value: 1, Years: []int{2011, 2014, 2019}},
{Name: "みかん", Value: 2, Years: []int{2011}},
{Name: "ぎょうざ", Value: 3, Years: []int{2020}},
{Name: "ビーフストロガノフ", Value: 4, Years: []int{2011, 2019}},
{Name: "カレーライス", Value: 5, Years: []int{2012}},
{Name: "満漢全席", Value: 6, Years: []int{2015, 2019}},
})
}
サンプルが単純な物なので効果が伝わりにくいですが、テンプレートを書く手間が少し楽になった気がします。また break が入った事で if にマッチしない部分が無駄にループを回す事もなくなったので、Go 側から巨大な配列を事前にカットして渡す必要も無くなる事になります。