← Назад к вопросам

Как передать функцию как параметр другой функции?

1.0 Junior🔥 211 комментариев
#Основы Go

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Передача функции как параметра в Go

В Go передача функции как параметра другой функции является стандартной практикой благодаря поддержке функциональных типов (function types). Это мощный механизм, который позволяет реализовывать паттерны высшего порядка (higher-order functions), делегирование логики и создание гибких, расширяемых API.

Функциональные типы

В Go функция может быть передана как параметр только если её тип соответствует ожидаемому функциональному типу. Функциональный тип определяется как func(параметры) возвращаемый тип.

// Определяем функциональный тип
type Processor func(int) string

// Функция, принимающая Processor как параметр
func ProcessData(data int, processor Processor) string {
    return processor(data)
}

Пример использования

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

package main

import (
    "fmt"
    "sort"
)

func main() {
    numbers := []int{5, 2, 9, 1, 5, 6}
    
    // Передаём функцию less как параметр в sort.Slice
    sort.Slice(numbers, func(i, j int) bool {
        return numbers[i] < numbers[j]
    })
    
    fmt.Println(numbers) // [1, 2, 5, 5, 6, 9]
}

Ключевые подходы и применение

1. Делегирование логики

Функции высшего порядка позволяют отделять общую логику от специфической:

func Filter(numbers []int, predicate func(int) bool) []int {
    result := []int{}
    for _, n := range numbers {
        if predicate(n) {
            result = append(result, n)
        }
    }
    return result
}

// Использование
evenNumbers := Filter(numbers, func(n int) bool {
    return n%2 == 0
})

2. Callback функции

Часто используются для обработки событий, асинхронных операций или middleware:

func HTTPRequest(url string, callback func([]byte, error)) {
    data, err := fetchFromNetwork(url)
    callback(data, err)
}

3. Адаптация поведения

Позволяет изменять поведение функций без изменения их реализации:

type Calculator func(float64, float64) float64

func Compute(a, b float64, calc Calculator) float64 {
    return calc(a, b)
}

// Разные реализации
add := func(a, b float64) float64 { return a + b }
multiply := func(a, b float64) float64 { return a * b }

Важные особенности

  • Замыкания (closures) — передаваемые функции могут быть замыканиями, сохраняющими контекст своего создания
  • Интерфейсы vs функциональные типы — иногда интерфейсы с одним методом (Single Method Interface) могут быть альтернативой, но функциональные параметры обычно более легковесны
  • Nil проверки — рекомендуется проверять, что передаваемый функциональный параметр не nil перед вызовом
  • Производительность — передача функций обычно не влияет на производительность критически, так как функции в Go являются first-class citizens

Практические советы

  1. Используйте именованные функциональные типы для улучшения читаемости и документирования кода
  2. Определяйте функции в том месте, где они используются, если они простые и одноразовые
  3. Сохраняйте сложные функции как переменные для повторного использования
  4. Комбинируйте с интерфейсами, когда нужна более сложная абстракция

Передача функций как параметров — это фундаментальная концепция в Go, которая поддерживает декларативный стиль программирования, улучшает тестируемость (легко передавать mock функции) и повышает модульность кода. Этот механизм активно используется в стандартной библиотеке (например, в sort, http.HandlerFunc, bufio.Scanner) и является основой многих популярных фреймворков.

Как передать функцию как параметр другой функции? | PrepBro