Может ли функция быть значением в `map` в Go?

Ответ

Да, безусловно. В Go функции являются гражданами первого класса (first-class citizens). Это означает, что их можно:

  • Присваивать переменным
  • Передавать в качестве аргументов в другие функции
  • Возвращать из других функций
  • Хранить в структурах данных, таких как map или slice.

Это мощный механизм для реализации паттернов проектирования, например, "Стратегия" или для создания обработчиков событий.

Пример:

package main

import "fmt"

func main() {
    // Объявляем map, где ключ - строка, а значение - функция
    operations := map[string]func(int, int) int{
        "add": func(a, b int) int { return a + b },
        "subtract": func(a, b int) int { return a - b },
        "multiply": func(a, b int) int { return a * b },
    }

    // Вызываем функцию из map по ключу
    result := operations["add"](10, 5)
    fmt.Println("Результат сложения:", result) // Выведет: 15
}

Что важно помнить:

  1. Соответствие типов: Сигнатура функции (типы аргументов и возвращаемых значений) должна точно соответствовать типу, указанному в объявлении map.
  2. Проверка на nil: Перед вызовом функции из map всегда проверяйте, что значение по ключу существует. Если ключа нет, вы получите nil, и попытка его вызова приведёт к панике.
    if op, ok := operations["divide"]; ok {
        op(10, 2)
    } else {
        fmt.Println("Операция не найдена")
    }