2015-10-22 10 views
5

Szablony przejść mają nieoczekiwane wyniki, jeśli używają dla mnie eq z index. Zobacz ten kod:Szablony przejść z wzorcami eq i indeksem

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

} 

spodziewam się mieć wyjściową

1 != 2 
2 = 2 
4 != 2 

ale mam

1 = 2 
2 = 2 
4 = 2 

Co należy zmienić, aby móc porównać członków tablicy Przejdź szablonów?

Odpowiedz

3

Używasz nieprawidłowej kolejności operatora i argumentu. Trzeba najpierw napisać operatora a następnie argumenty:

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

To jest bardziej czytelny i poręczny jak eq może zająć więcej niż tylko 2 argumenty, więc można napisać na przykład:

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

do prostych testów równości wielostronnych, eq (tylko) przyjmuje co najmniej dwa argumenty i porównuje sekund, a następnie do pierwszego, w efekcie powrotu

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

(W przeciwieństwie do || Przejdź jednak eq jest wywołanie funkcji, a wszystkie argumenty będą oceniane)

Dzięki tej zmianie wyjście (spróbuj go na Go Playground).

1 != 2 

2 = 2 

4 != 2 

Uwaga:

nie jest wymagane wprowadzenie zmiennej „pętla”, akcja {{range}} zmienia kropkę do bieżącego elementu:

... kropka jest ustawiony na kolejnych elementach tablicy, kawałek, lub map ...

Więc można uprościć szablonu, jest to równoznaczne z Ciebie:

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

Należy również pamiętać, że możesz samodzielnie tworzyć zmienne w szablonie, co jest zalecane, jeśli używasz tego samego wyrażenia wielokrotnie, co jest nietrywialne (na przykład index . 0).Jest to także równoznaczne z szablonu:

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

Należy również zauważyć, że w tym konkretnym przypadku, ponieważ to, co chcesz wstawić w if i else oddziałów zarówno zawierających znak =, nie trzeba 2 oddziały, = musi być wyprowadzony w obu przypadkach, potrzebujesz tylko dodatkowego znaku !, jeśli nie są one równe. Dlatego następujący szablon końcowy jest również równoważny Twojemu:

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