Тип функциональной переменной в Go

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

func myFunc(f interface{})

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

3 ответа

Решение

Предполагая, что вы буквально имеете в виду любую функцию, вы можете сделать переключение типа (которое будет конкретным):

switch v.(type) {
case func() int:
case func() string:
}

Или вы могли бы использовать reflect Пакет для определения типа:

if reflect.TypeOf(v).Kind() != reflect.Func {
    // error here
}

Это решение во время выполнения. Кроме этого, вы ничего не можете сделать. Недостатком этого является то, что компилятор не будет мешать кому-либо передавать нефункциональные значения.

Лично я бы избегал этого, и я ожидал бы конкретного прототипа func, например:

func myFunc(f func() string)

При этом вы с меньшей вероятностью будете иметь ошибки, когда компилятор знает, что это за типы.

Понятие "любая функция" может быть построено в Go в два этапа:

type MotherOfAllFuncs func()

Следующим шагом является завершение любой функции в замыкании, которое, как анонимный тип, совместимо с присваиванием MotherOfAllFuncs,

func() {
        anyFunction(with, any, parameters)
}

package main

import "fmt"

type f func()

func g(f f) {
        f()
}

func h(i int) {
        fmt.Println(21 * i)
}

func i() {
        fmt.Println(314)
}

func main() {
        g(func() { h(2) })
        g(func() { i() })
}

Детская площадка


Выход:

42
314

Функции первоклассных граждан в Go. Таким образом, они могут быть переданы и возвращены из функций, как и любой другой тип.

Вы можете определить свою функцию, чтобы взять функцию в качестве аргумента.

Читать далее - Функции первого класса и функции первого класса в Go.

Другие вопросы по тегам