Если упоминание var
является вашей основной проблемой, вы можете легко уронить его, изменив =
на :=
, например:
english := Greeting(func(name string) string {
return ("Hello, " + name);
})
Но вам даже не нужно преобразовывать свою функцию в Greeting
. Спецификация говорит это о типах функций :
Тип функции обозначает набор всех функций с одинаковыми параметрами и типами результатов.
А это про тип личности :
Два типа функций идентичны, если они имеют одинаковое количество параметров и значений результатов, соответствующие параметры и типы результатов идентичны, и либо обе функции являются переменными, либо ни одна из них не является. Имена параметров и результатов не обязательно должны совпадать.
Это означает, что каждая функция имеет свой собственный тип функции. Если две функции имеют одинаковую сигнатуру (тип параметра и тип результата), они совместно используют один тип функции. Написав 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
показывают два разных способа кодирования одной и той же вещи. Опять же, я не говорю, что это лучшее решение, но более обычный и более гибкий способ достижения того же эффекта.