如果提到var 是您的主要问题,您可以轻松地将其删除,方法是将= 更改为:=,如下所示:
english := Greeting(func(name string) string {
return ("Hello, " + name);
})
但您甚至不必将函数转换为 Greeting。规范中提到了function types:
函数类型表示具有相同参数和结果类型的所有函数的集合。
关于type identity:
如果两个函数类型相同,如果它们具有相同数量的参数和结果值,对应的参数和结果类型相同,并且两个函数都是可变的,或者两者都不是。参数和结果名称不需要匹配。
这意味着每个函数都有自己的函数类型。如果两个函数具有相同的签名(参数和结果类型),则它们共享一种函数类型。通过编写type Greeting func...,您只是为特定函数类型命名,而不是定义新函数类型。
所以下面的代码可以工作,我希望能展示在 Go 中使用函数类型的正确方法:
package main
import "fmt"
type Greeting func(name string) string
func say(g Greeting, n string) { fmt.Println(g(n)) }
func french(name string) string { return "Bonjour, " + name }
func main() {
english := func(name string) string { return "Hello, " + name }
say(english, "ANisus")
say(french, "ANisus")
}
请注意,我还从您的 english 函数中删除了分号和括号。如果非必要,Go 开发人员不会使用这些标点符号。
更新:现在您已经提供了示例代码,我可以清楚地理解问题所在。
为此,您的代码已经足够好,没有太多其他方法可以做到这一点。如果您愿意,可以在调用该方法之前进行转换:
english := func(name string) string { return "Hello, " + name }
Greeting(english).exclamation("ANisus")
但我不确定这是一种改进。我只是说,对于您想做的事情,似乎没有其他方法可以编写代码。
也就是说,如果我们不想更改您的类型。我的意思是,在函数类型上调用方法的整个想法似乎有点奇怪。不是说错了,而是有点少见。以更常见的方式实现相同效果的另一种方法是通过结构类型并为函数提供一个字段。像这样的:
package main
import "fmt"
type Greeting struct {
say func(name string) string
}
func newGreeting(f func(string) string) *Greeting {
return &Greeting{say: f}
}
func (g *Greeting) exclamation(name string) string { return g.say(name) + "!" }
func main() {
english := &Greeting{say: func(name string) string {
return "Hello, " + name
}}
french := newGreeting(func(name string) string {
return "Bonjour, " + name
})
fmt.Println(english.exclamation("ANisus"))
fmt.Println(french.exclamation("ANisus"))
}
这里english 和french 显示了编码同一事物的两种不同方式。同样,我并不是说这是更好的解决方案,而是一种更常用、更灵活的方式来实现相同的效果。