通过循环遍历映射表实现索引的简单方法:
package main
import (
"fmt"
)
func main() {
mm := map[string]int{"xx" : 1, "gg" : 2}
cnt := 0
for a, b:= range mm{
fmt.Println("a", a, "b",b, "c" , cnt)
cnt++
}
fmt.Println("Hello, playground")
}
并打印出:
a xx b 1 c 0
a gg b 2 c 1
Hello, playground
仅仅使用模板操作是不够的,但您可以注册一个提供必要帮助的函数。
您可以注册一个返回函数(闭包)的函数,每次调用时交替返回其返回值(就像“奇数”和“偶数”索引一样):
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
如果您希望在奇数和偶数迭代中获得不同的输出,可以在{{if}}
操作中调用$e
,如下所示:
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()
返回一个函数值,一个具有访问类型为bool
的本地变量e
的闭包。当您稍后执行{{call $e}}
时,您不是在调用isEven()
Go函数,而是调用该函数返回的函数(闭包)并存储在$e
中。该闭包引用了本地bool
变量e
,它直到可访问isEvent()
返回的函数时才被释放。
因此,每当您执行{{call $e}}
时,它会调用闭包,闭包“拥有”类型为bool
的变量e
,其值在这个$e
的调用之间得以保留。
如果您在模板中再次调用isEvent
,那么它将返回一个新函数(闭包),包装第一个isEvent()
调用返回的闭包的第一个包装变量实例独立的新实例。
e
没有被重置为false? - DiCapriorange
迭代映射时,您都会得到不同的顺序——这表明映射中没有索引概念。{{range $key, $element := .Map}}
{{$index := index .Map $key}}
{{end}}
even
吗?还是可以使用 CSS 样式 (:nth-child(odd)
,:nth-child(even)
) 并忘记even
? - kennytm