【问题标题】:Using methods with multiple return values使用具有多个返回值的方法
【发布时间】:2019-04-28 01:53:59
【问题描述】:

我正在尝试编写一个模板(使用 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 但根本无法让它工作。

感谢您的任何建议!

【问题讨论】:

  • 不能从模板调用函数,这是真的。那么你会继续使用wrapper function 吗?展示你目前的作品,让人们帮助你完成它。
  • 相关:Text/template: “can't call method/function with 0 results.”。解决方法是一样的:你必须创建一个自定义函数。
  • 我试图创建一个函数(FirstValue),它将另一个函数作为其参数,然后只返回原始输出的第一个值。不幸的是,我似乎无法在模板中传递该方法,因此它不起作用:{{FirstValue .Baz}} 调用 .Baz() }} 而不是传递它,所以这是不行的。跨度>

标签: go go-templates


【解决方案1】:

您将无法调用在模板中返回两个值的函数,除非其中一个值出错。这样可以保证您的模板在运行时工作。如果您有兴趣,有一个很好的答案可以解释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}}`

希望这会有所帮助。 :)

【讨论】:

  • 非常感谢。我虽然可能是这样。我的解决方案涉及通过迭代一组项目并使用它们进行一些(链接的)工作来进行一组计算。我试图避免多次迭代的开销,这实际上会使所需的计算翻倍。不过,我喜欢将结构传回来的想法,这很有意义。谢谢!
【解决方案2】:

也有可能返回具有多个字段的结构并使用它们。

type Result struct {
    First string
    Second string
}

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

然后在模板中使用

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

【讨论】:

    【解决方案3】:

    我最近遇到了与此类似的问题并遇到了这个问题。我认为这可能会更干净一些。它不需要您创建多个新函数:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-09
      • 2013-11-09
      • 1970-01-01
      • 1970-01-01
      • 2017-08-30
      • 2013-02-12
      • 1970-01-01
      相关资源
      最近更新 更多