Можно ли создать методы для типов функций? - PullRequest
1 голос
/ 04 июля 2019

Я знаю, что методы могут быть созданы для определенных типов

Пример

type MyFunc func() int

func (f MyFunc) eval() int {
    return f()
}

func main() {
   var randomFunction MyFunc = func() int {
      return 1;
  }

  fmt.Println(randomFunction.eval()) // prints 1
}

Но randomFunction должен был быть объявлен как тип MyFunc. Если объявление выглядело как

randomFunction := func() int {
  return 1;
}

вызов метода не сработал.

Мой вопрос: можно ли создать методы для каждой функции, например, типа func () int.

Я знаю, что Go не функционален и не содержит слишком много функциональных идиом, но я ищу подход, аналогичный показу экземпляра Haskell для функций:

instance Show (Int -> Int) where
   show op = show "Function with 1 Int param and Int return type"

1 Ответ

3 голосов
/ 04 июля 2019

Методы привязаны к типу. MyFunc.eval() связан с типом MyFunc.

Это:

randomFunction := func() int {
  return 1
}

Является кратким объявлением переменной , которое создает переменную с именем randomFunction и использует литерал функции для предоставления ей начального значения, тип которого будет анонимным типом функции: func() int. Этот тип не имеет функции eval() (анонимные типы имеют нулевые методы).

Но вы можете использовать преобразование типа , чтобы преобразовать его в MyFunc, и полученное значение будет иметь этот метод:

randomFunction2 := func() int {
    return 1
}
fmt.Println(MyFunc(randomFunction2).eval()) // prints 1

Приведенное выше преобразование не меняет тип randomFucntion2, конечно.

Если вы используете преобразование в кратком объявлении переменной, randomFunction3 будет иметь статический тип MyFunc, а "всегда" будет иметь метод eval():

randomFunction3 := MyFunc(func() int {
    return 1
})
fmt.Println(randomFunction3.eval()) // prints 1

Также обратите внимание, что часто вам даже не нужно вручную преобразовывать значения вашей функции, как если бы это был анонимный тип, преобразование будет происходить автоматически.

Например, если у вас есть функция, которая принимает значение типа MyFunc:

func handle(f MyFunc) {
    fmt.Println(f.eval())
}

Вы можете передать ему randomFunction2:

handle(randomFunction2) // This is OK

Вышеописанное работает, потому что значение randomFunction2 равно , присваиваемому типу (переменной) MyFunc (они имеют одинаковый базовый тип). Подробнее см. Пользовательский тип, переданный в функцию в качестве параметра .

Попробуйте примеры на Go Playground .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...