Можно ли присвоить функцию переменной в Swift?

Ответ

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

  • Присваивать их переменным и константам
  • Передавать в качестве аргументов другим функциям
  • Возвращать из функций

Примеры:

// 1. Присвоение функции переменной
func multiply(_ a: Int, _ b: Int) -> Int { return a * b }
let mathOperation: (Int, Int) -> Int = multiply
let result = mathOperation(5, 3) // 15

// 2. Массив функций
let operations: [(Int, Int) -> Int] = [
    { $0 + $1 }, // Сложение
    { $0 - $1 }, // Вычитание
    multiply     // Умножение
]

// 3. Опциональный тип функции
var optionalFunction: ((String) -> Void)?
optionalFunction = { print($0) }
optionalFunction?("Hello") // Вызов через optional chaining

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

  • Тип переменной должен точно соответствовать сигнатуре функции (параметры и возвращаемый тип).
  • Для методов экземпляра используется связанная функция (bound method), которая захватывает контекст self.
  • Для улучшения читаемости сложных сигнатур используйте typealias.

Ответ 18+ 🔞

О, слушай, а ведь в Swift функции — это вообще отдельная песня, блядь! Не просто какие-то там куски кода, которые ты вызываешь, а полноценные объекты первого класса, ёпта! Это значит, что с ними можно делать всё то же самое, что и с каким-нибудь Int или String. Ну, почти всё.

Представь себе: ты можешь взять функцию и сунуть её в переменную, как какой-нибудь бутерброд в холодильник. Можешь запихнуть её в массив, как носки в ящик. Можешь передать её другой функции на растерзание, а та может её сожрать и выплюнуть обратно, уже переваренную. Во какие дела, блядь!

Вот смотри, как это выглядит, чтобы не быть голословным:

// 1. Суём функцию в переменную, как в норку
func multiply(_ a: Int, _ b: Int) -> Int { return a * b }
let mathOperation: (Int, Int) -> Int = multiply // Вот, поймали функцию и посадили в коробку `mathOperation`
let result = mathOperation(5, 3) // Достали из коробки и использовали. Результат — 15, ебать!

// 2. Делаем из функций коллекцию, как из марок
let operations: [(Int, Int) -> Int] = [
    { $0 + $1 }, // Сложение, на лету создали, хитрая жопа
    { $0 - $1 }, // Вычитание
    multiply     // А это наша старая знакомая
]
// Теперь у тебя целый арсенал, выбирай чем бить!

// 3. А можно и опциональную функцию завести. Вдруг она сегодня не в духе?
var optionalFunction: ((String) -> Void)?
optionalFunction = { print($0) } // Ага, вот теперь она есть!
optionalFunction?("Hello") // Вызов через optional chaining, на всякий случай, чтобы не схлопотать краш, если она nil

А теперь главное, чтобы не обосраться:

  • Сигнатура — это святое, блядь! Тип твоей переменной должен совпадать с функцией точь-в-точь. Нельзя (Int) -> String запихнуть в (String) -> Int. Компилятор тебя сожрёт, и будет прав, пидарас шерстяной.
  • С методами экземпляра (instance methods) есть нюанс — они превращаются в связанные функции. Это значит, что они тащат за собой свой контекст, своего self. Представь собаку на поводке — куда функция, туда и объект.
  • Если сигнатура функции выглядит как чертёж космического корабля — (Int, (String) -> Bool) -> ((Double) -> Void)? — не мучайся. Используй typealias, дай этому монстру человеческое имя, и жить станет проще, в рот меня чих-пых!

Вот так-то. Функции в Swift — это не просто инструмент, это целая философия, блядь. Освоишь — и код твой станет гибким, как гимнастка, и мощным, как… ну, в общем, очень мощным.