Функции в языке Go как аргументы
В Go функции являются объектами первого класса; их можно присваивать, передавать и использовать так же, как обычные переменные. Передача функции в качестве аргумента другой функции — распространённый шаблон программирования в Go, часто используемый в таких сценариях, как обратные вызовы и паттерн «стратегия».
Функция, присвоенная переменной
Функцию можно присвоить переменной, и функцию можно вызвать через эту переменную:
Пример
import (
"fmt"
"math"
)
func main() {
/* Присвоить анонимную функцию переменной getSquareRoot */
getSquareRoot := func(x float64) float64 {
return math.Sqrt(x)
}
/* Вызвать функцию через переменную */
fmt.Println(getSquareRoot(9)) // Вывод: 3
fmt.Println(getSquareRoot(16)) // Вывод: 4
}
Результат выполнения приведённого выше кода:
3 4
Передача функций в качестве аргументов
При передаче функции в качестве аргумента другой функции принимающая функция должна объявить соответствующий параметр типа функции. В следующем примере определяетсяapplyфункция, которая принимает функцию операции и два операнда, выполняя любую заданную операцию над этими двумя числами:
Пример
import (
"fmt"
"math"
)
/* Определяем функцию, которая принимает параметр op типа функции */
/* тип op — func(float64, float64) float64, то есть он принимает два параметра float64 и возвращает float64 */
func apply(op func(float64, float64) float64, a, b float64) float64 {
return op(a, b)
}
func main() {
/* Определяем функцию сложения */
add := func(a, b float64) float64 {
return a + b
}
/* Определите функцию умножения */
multiply := func(a, b float64) float64 {
return a * b
}
/* Передайте функцию add как фактический аргумент в apply */
fmt.Println(apply(add, 3, 4)) // Вывод: 7
/* Передайте функцию multiply как фактический аргумент в apply */
fmt.Println(apply(multiply, 3, 4)) // Вывод: 12
/* Вы также можете передать анонимную функцию напрямую */
fmt.Println(apply(func(a, b float64) float64 {
return math.Pow(a, b) // a в степени b
}, 2, 10)) // Вывод: 1024
}
Результат выполнения приведённого выше кода:
7 12 1024
Практическое применение: пользовательские правила сортировки
Одно из самых распространённых применений функций в качестве аргументов — пользовательские правила сортировки. Стандартная библиотека Gosort.SliceОна принимает функцию сравнения в качестве параметра:
Пример
import (
"fmt"
"sort"
)
func main() {
nums := []int{5, 2, 8, 1, 9, 3}
/* Передайте функцию сравнения в качестве фактического аргумента в sort.Slice, чтобы отсортировать от наименьшего к наибольшему */
sort.Slice(nums, func(i, j int) bool {
return nums[i] < nums[j]
})
fmt.Println("Ascending:", nums) // Вывод: Ascending: [1 2 3 5 8 9]
/* Передайте другую функцию сравнения, чтобы отсортировать от наибольшего к наименьшему */
sort.Slice(nums, func(i, j int) bool {
return nums[i] > nums[j]
})
fmt.Println(Descending:, nums) // Вывод: descending: [9 8 5 3 2 1]
}
Результат выполнения приведённого выше кода:
升序:[1 2 3 5 8 9] 降序:[9 8 5 3 2 1]
Передавая разные функции в качестве аргументов, ту жеsort.Sliceпозволяет реализовать совершенно иную логику сортировки. Именно в этом заключается основная ценность функций как аргументов —параметризация поведения, делающая код более гибким и повторно используемым.。