Go templates with eq and index

huangapple go评论156阅读模式
英文:

Go templates with eq and 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模板中比较数组成员?

英文:

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?

答案1

得分: 15

eq 是一个前缀操作:

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

Playground: http://play.golang.org/p/KEfXH6s7N1.

英文:

eq is a prefix operation:

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

Playground: http://play.golang.org/p/KEfXH6s7N1.

答案2

得分: 7

你使用了错误的运算符和参数顺序。你需要先写运算符,然后是操作数:

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

这样更易读和方便,因为eq可以接受多个参数,所以你可以写成:

{{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)更改为当前项:

...dot is set to the successive elements of the array, slice, or map...

所以你可以简化你的模板,下面的模板与你的等价:

{{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分支中输出的内容都包含=符号,你不需要两个分支,=需要在两种情况下输出,只需要在它们不相等时加一个额外的!符号。所以下面的最终模板也与你的模板等价:

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

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}}

huangapple
  • 本文由 发表于 2015年10月22日 21:21:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/33282061.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定