#13.1 golang Функция как объект первого класса: Анонимные функции, колбэки, замыкания
Primary tabs
Forums:
Анонимная функция как тип данных
Мы можем:
- присваивать функцию переменной,
- принимать функцию как аргумент в другую функцию
- и возвращать функцию как результат работы какой-то функции
- а также иметь функцию как поле какой-то структуры (о структурах мы поговорим позже) ,т.е. по сути функция в каком-то смысле тоже выступает типом данных
Например, обычная функция определяется в отдельном блоке. У нее есть имя, в данном случае doNothing:
// обычная функция
func doNothing() {
fmt.Println("Это обычная функция")
}Анонимная функция не имеет имени и определяется там, где вы захотите, при этом имя функции не указывается, а сразу после ключевого слово func в скобках указываем входные параметры:
func main() {
// анонимная функция
func(in string) {
fmt.Println("anon func out:", in)
}("Привет!")
}
- здесь мы определили функцию и тут же вызвали её с аргументом "Привет!"
Присваивание переменной значения-функции
Также анонимную функцию можно присвоить какой-то переменной и потом вызвать ее. Мы будем обращаться к такой переменной как к функции, указывая для вызова скобки после имени переменной-функции:
func main() {
printer := func(in string) {
fmt.Println("printer outs:", in)
}
printer("Привет!")
}
Коллбэк и Определение отдельного типа данные для сигнатуры функции
Иногда вам приходится в нескольких местах объявлять функции, передавать их куда-то, поэтому можно определить специальный тип функции при помощи ключевого слова type:
// определяем тип функции: //в данном случае принимаем один аргумент int и возвраем int type myFunctionType func(int) int
-- сигнатура функции тут выступает базовым типом для нашего myFunctionType.
Используем опеределенный выше тип, для описания типа коллбэка, который принимает функция и затем вызывает:
type myFunctionType func(int) int
func main() {
// просто анонимная функция
incFunction := func(value int) int {
return value + 1
}
// используем пользовательский тип для параметра-колбэка
worker := func(callback myFunctionType) {
fmt.Println(callback(1))
}
worker(incFunction)
}
Замыкания
В golang можно создавать замыкания:
func main() {
// функция возвращает замыкание
fixedSummer := func(sumWithThis int) myFunctionType {
return func(value int) int {
// sumWithThis будет определено
// через механизм замыкания из-за пределов
// тела нашей анонимной функции
return value + sumWithThis
}
}
// получим замыкание над значением 5
runner := fixedSummer(5)
// выполним замкнутую функцию
// -- она прибавит 5 к переданному агрументу (2)
fmt.Println(runner(2)) // 7
}
-- в этом примере мы получаем sumWithThis внутри возвращаемой анонимной функции именно через механизм замыкания, захватывая это значение из-за пределов тела самой анонимной функции.
Из-за того, что golang имеет сборщик мусора переменная sumWithThis не удаляется сразу, а остается в памяти, пока мы храним ссылку на возвращенную анонимную функцию, которая в свою очередь ссылается на эту переменную.
- Log in to post comments
- 64 reads