2015-07-08 8 views
5

Ich versuche, eine Vorlage (mit HTML/Vorlage) zu schreiben und übergibt ihr eine Struktur, die einige Methoden hat, von denen viele mehrere Werte zurückgeben. Gibt es eine Möglichkeit, auf diese innerhalb der Vorlage zuzugreifen? Ich möchte in der Lage sein, etwas zu tun:Verwenden von Methoden mit mehreren Rückgabewerten

package main 

import (
     "fmt" 
     "os" 
     "text/template" 
) 

type Foo struct { 
    Name string 
} 

func (f Foo) Baz() (int, int) { 
    return 1, 5 
} 

const tmpl = `Name: {{.Name}}, Ints: {{$a, $b := .Baz}}{{$a}}, {{b}}` 

func main() { 

    f := Foo{"Foo"} 

    t, err := template.New("test").Parse(tmpl) 
    if err != nil { 
     fmt.Println(err) 
    } 

    t.Execute(os.Stdout, f) 

} 

Aber offensichtlich funktioniert das nicht. Gibt es keinen Weg um es herum?

Ich habe als eine anonyme Struktur in meinem Code zu erstellen:

data := struct { 
    Foo 
    a int 
    b int 
}{ 
    f, 
    0, 
    0, 
} 
data.a, data.b = f.Baz() 

Und das nebenbei, würde aber viel lieber etwas in der Vorlage haben. Irgendwelche Ideen? Ich habe auch versucht, eine Wrapper-Funktion zu schreiben, die ich zu funcMaps hinzugefügt habe, aber ich konnte das nie zum Funktionieren bringen.

Vielen Dank für Anregungen!

+0

nicht Funktion aus Vorlage nennen können, das stimmt. Also werden Sie mit der Wrapper-Funktion fortfahren? Zeigen Sie Ihre aktuellen Arbeiten daran und lassen Sie die Leute Ihnen helfen, es auszuarbeiten. –

+0

Related: [Text/Vorlage: "kann Methode/Funktion mit 0 Ergebnisse nicht aufrufen."] (Http://stackoverflow.com/questions/31221849/text-template-cant-call-method-function-with-0 -Ergebnisse). Die Lösung ist die gleiche: Sie müssen eine benutzerdefinierte Funktion erstellen. – icza

+0

Ich habe versucht, eine Funktion (FirstValue) zu erstellen, die eine andere Funktion als Argument verwendet und dann nur den ersten Wert der ursprünglichen Ausgabe zurückgibt. Leider scheint es so, dass ich die Methode nicht in der Vorlage weitergeben kann, so dass es nicht funktioniert: {{FirstValue .Baz}} ruft .Baz()}} auf, anstatt es zu übergeben, also ist es ein Nein. –

Antwort

5

Sie können keine Funktion aufrufen, die zwei Werte in einer Vorlage zurückgibt, es sei denn, einer dieser Werte ist ein Fehler. Dies ist so, dass Ihre Vorlage garantiert zur Laufzeit funktioniert. Es gibt eine gute Antwort, die erklärt, dass here, wenn Sie interessiert sind.

Um Ihr Problem zu lösen, müssen Sie entweder 1) Ihre Funktion in zwei separate Getter-Funktionen zu brechen, die Sie an der entsprechenden Stelle in Ihrer Vorlage aufrufen können; oder 2) Lassen Sie Ihre Funktion eine einfache Struktur mit den Werten zurückgeben.

Ich kann nicht sagen, was für Sie besser wäre, weil ich wirklich keine Ahnung habe, was Ihre Implementierung erfordert. Foo und Baz geben nicht viele Hinweise. ;)

Hier ist ein schnell-n-dirty Beispiel Option ein:

type Foo struct { 
    Name string 
} 

func (f Foo) GetA() (int) { 
    return 1 
} 

func (f Foo) GetB() (int) { 
    return 5 
} 

Und dann die Vorlage entsprechend modifizieren:

const tmpl = `Name: {{.Name}}, Ints: {{.GetA}}, {{.GetB}}` 

Hoffentlich ist das eine Hilfe. :)

+0

Vielen Dank. Ich dachte, das wäre wahrscheinlich der Fall. Meine Lösung besteht darin, eine Reihe von Berechnungen durchzuführen, indem ich eine Reihe von Elementen durchlaufen und einige (verknüpfte) Arbeiten mit ihnen ausführen kann.Ich versuche, den Aufwand zu vermeiden, mehrere Male zu durchlaufen, was die erforderlichen Berechnungen wesentlich verdoppeln würde. Ich mag die Idee, eine Struktur zurückzugeben, aber das macht viel Sinn. Vielen Dank! –

1

Es gibt auch die Möglichkeit, Struktur mit mehreren Feldern zurückzugeben und sie zu verwenden.

type Result struct { 
    First string 
    Second string 
} 

func GetResult() Result { 
    return Result{First: "first", Second: "second"} 
} 

Und dann in Vorlage verwenden

{{$result := GetResult}} 
{{$result.First}} - {{$result.Second}} 
Verwandte Themen