12

eq在我使用with时,Go 模板有一些意想不到的结果index。请参阅此代码:

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 模板中的数组成员?

4

2 回答 2

15

eq是前缀操作:

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

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

于 2015-10-22T13:39:05.343 回答
7

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

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

这更具可读性和方便性,因为eq它可以接受超过 2 个参数,因此您可以编写例如:

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

对于更简单的多路相等测试,eq(仅)接受两个或多个参数并比较第二个和第一个之后的参数,返回有效

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

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

通过此更改输出(在Go Playground上尝试):

1 != 2

2 = 2

4 != 2

笔记:

您不需要引入“循环”变量,该{{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}}
于 2015-10-22T13:39:22.470 回答