eq
をindex
と一緒に使用すると、Goテンプレートで予期しない結果が発生します。このコードを参照してください:
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}}
間違った演算子と引数の順序を使用しています。最初に演算子を記述し、次にオペランドを記述する必要があります。
{{if eq (index $n 0) (index $n 1)}}
eq
は2つ以上の引数を取ることができるため、これはより読みやすく便利です。たとえば、次のように記述できます。
{{if eq (index $n 0) (index $n 1) (index $n 2)}}
より単純な多元等価性テストの場合、eq(のみ)は2つ以上の引数を受け入れ、2番目以降を比較して有効に戻ります。
arg1==arg2 || arg1==arg3 || arg1==arg4 ...
(ただし、Goの||とは異なり、eqは関数呼び出しであり、すべての引数が評価されます。)
これで出力を変更します( Go Playground で試してください):
1 != 2
2 = 2
4 != 2
注:
「ループ」変数を導入する必要はありません。{{range}}
アクションはドットを現在のアイテムに変更します。
...ドットは、配列、スライス、またはマップの連続する要素に設定されます...
したがって、テンプレートを単純化できます。これは、テンプレートと同等です。
{{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}}
また、この特定のケースでは、if
ブランチとelse
ブランチの両方に=
記号が含まれているため、2つのブランチは必要ありません。=
はで出力する必要があります。どちらの場合も、等しくない場合は、追加の!
記号が必要です。したがって、次の最終的なテンプレートもあなたのものと同等です。
{{range .}}{{$0 := index . 0}}{{$1 := index . 1}}
{{$0}} {{if ne $0 $1}}!{{end}}= {{$1}}
{{end}}