Go templates have some unexpected results when using eq
with index
for me. See this code:
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},
})
}
I expect to have output
1 != 2
2 = 2
4 != 2
but I get
1 = 2
2 = 2
4 = 2
What should I change to be able to compare array members in go templates?
You use wrong operator and argument order. You have to first write the operator and then the operands:
{{if eq (index $n 0) (index $n 1)}}
This is more readable and handy as eq
can take more than just 2 arguments, so you could write for example:
{{if eq (index $n 0) (index $n 1) (index $n 2)}}
For simpler multi-way equality tests, eq (only) accepts two or more arguments and compares the second and subsequent to the first, returning in effect
arg1==arg2 || arg1==arg3 || arg1==arg4 ...
(Unlike with || in Go, however, eq is a function call and all the arguments will be evaluated.)
With this change the output (try it on the Go Playground):
1 != 2
2 = 2
4 != 2
Note:
You are not required to introduce a "loop" variable, the {{range}}
action changes the dot to the current item:
...dot is set to the successive elements of the array, slice, or map...
So you can simplify your template, this is equivalent to yours:
{{range .}}
{{index . 0}} {{if eq (index . 0) (index . 1)}}={{else}}!={{end}} {{index . 1}}
{{end}}
Also note that you can create variables in the template yourself, which is recommended if you use the same expression multiple times which is nontrivial (such as index . 0
). This is also equivalent to your template:
{{range .}}{{$0 := index . 0}}{{$1 := index . 1}}
{{$0}} {{if eq $0 $1}}={{else}}!={{end}} {{$1}}
{{end}}
Also note that in this specific case since the things you want to output in the if
and else
branches both contain the =
sign, you don't need 2 branches, =
needs to be outputted in both cases, you just need an extra !
sign if they are not equal. So the following final template is also equivalent to yours:
{{range .}}{{$0 := index . 0}}{{$1 := index . 1}}
{{$0}} {{if ne $0 $1}}!{{end}}= {{$1}}
{{end}}
eq
is a prefix operation:
{{if eq (index $n 0) (index $n 1)}}={{else}}!={{end}}
Playground: http://play.golang.org/p/KEfXH6s7N1.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With