使用具有多个 return 值的方法
Using methods with multiple return values
我正在尝试编写一个模板(使用 html/template)并向其传递一个结构,该结构附加了一些方法,其中许多 return 多个值。有没有办法从模板中访问这些?我希望能够做类似的事情:
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 但根本无法让它工作。
感谢任何建议!
您将无法调用模板中 return 有两个值的函数,除非其中一个值是错误的。这是为了保证您的模板在运行时工作。有一个很好的答案可以解释 ,如果您感兴趣的话。
要解决您的问题,您需要 1) 将您的函数分解为两个单独的 getter 函数,您可以在模板中的适当位置调用它们;或 2) 让你的函数 return 成为一个简单的结构,其中包含值。
我不知道哪个更适合你,因为我真的不知道你的实施需要什么。 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}}`
希望这对您有所帮助。 :)
也可以return构造多个字段并使用它们。
type Result struct {
First string
Second string
}
func GetResult() Result {
return Result{First: "first", Second: "second"}
}
然后在模板中使用
{{$result := GetResult}}
{{$result.First}} - {{$result.Second}}
我最近遇到了一个类似的问题,遇到了这个问题。我认为这可能会更清洁一些。它不需要您创建多个新功能:
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)
}
我正在尝试编写一个模板(使用 html/template)并向其传递一个结构,该结构附加了一些方法,其中许多 return 多个值。有没有办法从模板中访问这些?我希望能够做类似的事情:
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 但根本无法让它工作。
感谢任何建议!
您将无法调用模板中 return 有两个值的函数,除非其中一个值是错误的。这是为了保证您的模板在运行时工作。有一个很好的答案可以解释
要解决您的问题,您需要 1) 将您的函数分解为两个单独的 getter 函数,您可以在模板中的适当位置调用它们;或 2) 让你的函数 return 成为一个简单的结构,其中包含值。
我不知道哪个更适合你,因为我真的不知道你的实施需要什么。 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}}`
希望这对您有所帮助。 :)
也可以return构造多个字段并使用它们。
type Result struct {
First string
Second string
}
func GetResult() Result {
return Result{First: "first", Second: "second"}
}
然后在模板中使用
{{$result := GetResult}}
{{$result.First}} - {{$result.Second}}
我最近遇到了一个类似的问题,遇到了这个问题。我认为这可能会更清洁一些。它不需要您创建多个新功能:
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)
}