使用具有多个返回值的方法

问题描述 投票:5回答:3

我正在尝试编写一个模板(使用html / template)并向其传递一个附加了一些方法的结构,其中许多都返回多个值。有没有办法从模板中访问这些?我希望能够做到这样的事情:

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)

}

但显然这不起作用。周围没有办法吗?

我考虑在我的代码中创建一个匿名结构:

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

并传递它,但更喜欢在模板中有东西。有任何想法吗?我也尝试编写一个包装函数,我将其添加到funcMaps中,但根本无法使用它。

谢谢你的任何建议!

go go-templates
3个回答
4
投票

您将无法调用在模板中返回两个值的函数,除非其中一个值是错误。这样可以保证模板在运行时工作。如果您有兴趣,有一个很好的答案可以解释here

要解决您的问题,您需要1)将您的函数分解为两个单独的getter函数,您可以在模板中的适当位置调用它们;或者2)让你的函数返回一个包含里面值的简单结构。

我不知道哪个对你更好,因为我真的不知道你的实现需要什么。 Foo和Baz没有提供很多线索。 ;)

这是第一个选项的快速例子:

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

希望这有一些帮助。 :)


1
投票

还可以返回包含多个字段的struct并使用它们。

type Result struct {
    First string
    Second string
}

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

然后在模板中使用

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

0
投票

我最近遇到了类似这个问题,遇到了这个问题。我想这可能会更清洁一些。它不需要您创建多个新功能:

const tmpl = `Name: {{.Name}}, Ints: {{BazWrapper .}}`

func main() {

    f := Foo{"Foo"}

    funcMap := template.FuncMap{
        "BazWrapper": func(f Foo) string {
            a, b := f.Baz()
            return fmt.Sprintf("%d, %d", a, b)
        },
    }

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

    t.Execute(os.Stdout, f)

}
© www.soinside.com 2019 - 2024. All rights reserved.