使用eq和index创建模板



Go模板在使用eqindex时有一些意想不到的结果。请看下面的代码:

package main
import (
    "os"
    "text/template"
)
func main() {
    const myTemplate = `
{{range $n := .}}
    {{index $n 0}} {{if (index $n 0) eq (index $n 1)}}={{else}}!={{end}} {{index $n 1}}
{{end}}
`
    t := template.Must(template.New("").Parse(myTemplate))
    t.Execute(os.Stdout,
        [][2]int{
            [2]int{1, 2},
            [2]int{2, 2},
            [2]int{4, 2},
        })
}

我期望输出

1 != 2
2 = 2
4 != 2

但是我得到

1 = 2
2 = 2
4 = 2

我应该改变什么,以便能够在go模板中比较数组成员?

eq是前缀操作:

{{if eq (index $n 0) (index $n 1)}}={{else}}!={{end}}

游乐场:http://play.golang.org/p/KEfXH6s7N1。

使用了错误的操作符和参数顺序。必须先写操作符,然后写操作数:

{{if eq (index $n 0) (index $n 1)}}

这是更具可读性和方便,因为eq可以接受两个以上的参数,所以你可以写,例如:

{{if eq (index $n 0) (index $n 1) (index $n 2)}}

对于更简单的多路相等性测试,eq (only)接受两个或多个参数,并将第二个及后续的参数与第一个参数进行比较,实际上返回

arg1==arg2 || arg1==arg3 || arg1==arg4 ...

(然而,与Go中的||不同,eq是一个函数调用,所有参数都会被求值。)

这样改变输出(在Go Playground上试试):

1 != 2
2 = 2
4 != 2

注意:

您不需要引入"loop"变量,{{range}}动作将点更改为当前项目:

dot被设置为数组、切片或映射的连续元素

所以你可以简化你的模板,这相当于你的:

{{range .}}
    {{index . 0}} {{if eq (index . 0) (index . 1)}}={{else}}!={{end}} {{index . 1}}
{{end}}

还请注意,您可以自己在模板中创建变量,如果您多次使用相同的表达式(例如index . 0),建议您这样做。这也相当于你的模板:

{{range .}}{{$0 := index . 0}}{{$1 := index . 1}}
    {{$0}} {{if eq $0 $1}}={{else}}!={{end}} {{$1}}
{{end}}

还要注意,在这个特定的情况下,因为你想在ifelse分支中输出的东西都包含=符号,你不需要2个分支,=需要在两种情况下输出,如果它们不相等,你只需要一个额外的!符号。因此,下面的最终模板也等同于您的模板:

{{range .}}{{$0 := index . 0}}{{$1 := index . 1}}
    {{$0}} {{if ne $0 $1}}!{{end}}= {{$1}}
{{end}}