检测模板范围中的最后一项
在 Go 模板中,使用 range 操作迭代数组或切片可以方便地访问数组元素。但是,有时有必要将最后一个迭代与其他迭代区分开来。
考虑一个需要对范围中的最后一个元素进行不同格式设置的模板:
{{range $i, $e := .SomeField}} {{if $i}}, {{end}} $e.TheString {{end}}
此模板将生成输出例如:
one, two, three
要修改此行为并在最后一个元素之前输出“and”:
one, two, and three
需要确定范围中的哪个元素是最后一个。
虽然可以在模板之外跟踪数组的长度,但这种方法会产生一个静态值,无法考虑数组长度的变化。
解决方案在于利用 Go 的函数注入模板的功能。通过定义自定义函数,动态识别最后一个元素变得可行:
package main import ( "os" "reflect" "text/template" ) var fns = template.FuncMap{ "last": func(x int, a interface{}) bool { return x == reflect.ValueOf(a).Len() - 1 }, } func main() { t := template.Must(template.New("abc").Funcs(fns).Parse(`{{range $i, $e := .}}{{if $i}}, {{end}}{{if last $i $}}and {{end}}{{$e}}{{end}}.`)) a := []string{"one", "two", "three"} t.Execute(os.Stdout, a) }
这种方法利用反射来动态确定数组的长度并将其与当前索引 $i 进行比较。当索引匹配数组长度减一时,last 函数返回 true,表示当前元素是范围内的最后一个元素。
作为替代方案,也可以使用不带反射的 len 函数:
package main import ( "os" "text/template" ) func main() { t := template.Must(template.New("abc").Parse(`{{range $i, $e := .}}{{if $i}}, {{end}}{{if len .}}and {{end}}{{$e}}{{end}}.`)) a := []string{"one", "two", "three"} t.Execute(os.Stdout, a) }
以上是如何检测 Go 模板范围中的最后一项?的详细内容。更多信息请关注PHP中文网其他相关文章!