6

I'm trying to write a template (using html/template) and passing it a struct that has some methods attached to it, many of which return multiple values. Is there any way of accessing these from within the template? I'd like to be able to do something like:

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)

}

But obviously this doesn't work. Is there no way around it?

I've considered creating an anonymous struct in my code:

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

And passing that in, but would much prefer to have something in the template. Any ideas? I also tried writing a wrapper function which I added to funcMaps but could never get that to work at all.

Thanks for any suggestions!

4

3 に答える 3

6

テンプレートで 2 つの値を返す関数は、それらの値のいずれかがエラーでない限り呼び出すことはできません。これは、テンプレートが実行時に確実に機能するようにするためです。興味があれば、ここでそれを説明する素晴らしい答えがあります。

問題を解決するには、次のいずれかを行う必要があります。1) テンプレートの適切な場所で呼び出すことができる 2 つの個別のゲッター関数に関数を分割します。または 2) 関数に値を内部に含む単純な構造体を返すようにします。

あなたの実装に何が必要なのか本当にわからないので、どちらがあなたにとって良いかわかりません。Foo と Baz は多くの手がかりを与えません。;)

オプション 1 の簡単な例を次に示します。

type Foo struct {
    Name string
}

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

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

それに応じてテンプレートを変更します。

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

うまくいけば、これはいくつかの助けになります。:)

于 2015-07-08T10:52:03.887 に答える