Можно ли присвоить значение типа «функция» переменной типа пустой интерфейс (`any`)?

Ответ

Да, безусловно. Это возможно благодаря двум ключевым особенностям Go:

  1. Функции — это объекты первого класса (first-class citizens). Их можно присваивать переменным, передавать в качестве аргументов и возвращать из других функций, как и любые другие значения (числа, строки и т.д.).
  2. Пустой интерфейс (interface{} или его псевдоним any в Go 1.18+) может хранить значение абсолютно любого типа.

Соответственно, переменная типа any может хранить в себе функцию.

import "fmt"

func greet(name string) {
    fmt.Printf("Hello, %s!n", name)
}

func main() {
    // Присваиваем функцию переменной типа any
    // Обратите внимание: мы передаем саму функцию `greet`, а не ее результат `greet(...)`
    var i any = greet

    // Чтобы вызвать функцию, нужно выполнить утверждение типа (type assertion)
    if f, ok := i.(func(string)); ok {
        // Проверка 'ok' важна, чтобы избежать паники, если в 'i' лежит что-то другое
        f("World") // Выведет: Hello, World!
    } 
}

Ключевые моменты:

  • Современный Go: Начиная с версии 1.18, рекомендуется использовать псевдоним any вместо interface{} для лучшей читаемости.
  • Утверждение типа: Для использования значения, сохраненного в any, необходимо вернуть его к конкретному типу. Для функций важно точно указать их сигнатуру (например, func(string)).