您不仅可以使用模板操作来执行此操作,还可以注册一个提供必要帮助的函数。
您可以注册一个返回一个函数(闭包)的函数,该函数在每次调用时都会改变其返回值(确切地说,“奇数”和“偶数”索引的交替方式):
func isEven() func() bool { e := false return func() bool { e = !e return e }}我将其命名
isEven()为不与ravel的碰撞
even()。使用它:
func main() { t := template.Must(template.New("").Funcs(template.FuncMap{ "isEven": isEven, }).Parse(templ)) m := map[string]string{ "a": "A", "b": "B", "c": "C", "d": "D", } if err := t.Execute(os.Stdout, m); err != nil { panic(err) }}const templ = `{{$e := isEven}}{{- range $k, $v := . -}} [even:{{call $e}}] key={{$k}}; value={{$v}}{{end}}`输出(在Go Playground上尝试):
[even:true] key=a; value=A[even:false] key=b; value=B[even:true] key=c; value=C[even:false] key=d; value=D
如果您希望奇数和偶数迭代具有不同的输出,则可以调用
$e一个
{{if}}动作,如下所示:const templ = `{{$e := isEven}}{{- range $k, $v := . -}} [{{if call $e}}even{{else}}odd {{end}}] key={{$k}}; value={{$v}}{{end}}`输出(在Go Playground上尝试):
[even] key=a; value=A[odd ] key=b; value=B[even] key=c; value=C[odd ] key=d; value=D
引擎盖下
此模板操作:
{{$e := isEven}}创建一个名为的新模板变量
$e,其值将是
isEven()函数调用的结果(返回值)。
isEven()返回一个函数值,一个闭包可以访问
etype
的局部变量
bool。稍后再做时
{{call$e}},您不会调用isEven()Go函数,而是返回的函数(闭包)并存储在中
$e。该闭包引用了局部
bool变量
e,直到
isEvent()可以访问返回的函数之前,它才“释放”
。
因此,无论何时执行操作
{{call $e}},它都会调用闭包,该闭包“具有” e类型的变量
bool,其值在两次调用之间保留
$e。
如果您再次调用
isEvent模板,则将返回一个新函数(闭包),包装一个新的局部变量实例,该实例
e独立于第一次
isEvent()调用返回的闭包的第一个包装变量。



