- Писать и вызывать функции с параметрами и возвращаемыми значениями
- Использовать метки аргументов,
_и значения параметров по умолчанию - Писать замыкания, сокращать их и узнавать синтаксис замыкания в конце вызова
Представь, что в приложении цена билета считается в десяти разных местах. Когда правила изменятся, придётся исправлять десять мест — и одно ты наверняка забудешь. Решение — функция: ты пишешь код один раз, даёшь ему имя и вызываешь там, где нужно. Ты уже пользовался готовыми функциями print, sorted(), map — теперь напишешь свои.
Объявление функции
Функция начинается с ключевого слова func. В скобках записываются параметры вместе с типами, а после -> — тип возвращаемого значения. return возвращает результат. Если тело функции состоит из одного выражения, слово return можно не писать.
func greet(name: String) -> String {
return "Hello, \(name)!"
}
func square(_ x: Int) -> Int {
x * x
}
print(greet(name: "Aysel"))
print(square(7))
print(square(square(2)))Hello, Aysel! 49 16
Метки аргументов и значения по умолчанию
В Swift у каждого параметра может быть два имени, чтобы вызов читался как предложение: метка аргумента (пишется при вызове) и имя параметра (используется внутри функции). Функцию travel(from start: String, to end: String) вызывают так: travel(from: "Baku", to: "Shaki"). Если метка не нужна, вместо неё пишут _ — именно так устроен square(7).
Параметру можно задать значение по умолчанию: если опустить его при вызове, будет взято это значение. Ниже билет стоит 5 манатов для детей до 12 лет, 7,5 маната для студентов и 10 манатов для остальных.
func travel(from start: String, to end: String) {
print("Travelling from \(start) to \(end)")
}
func ticketPrice(for age: Int, isStudent: Bool = false) -> Double {
if age < 12 {
return 5.0
} else if isStudent {
return 7.5
}
return 10.0
}
travel(from: "Baku", to: "Shaki")
print(ticketPrice(for: 8))
print(ticketPrice(for: 20))
print(ticketPrice(for: 20, isStudent: true))Travelling from Baku to Shaki 5.0 10.0 7.5
Замыкания
Блок кода без имени, который можно сохранить в переменную и передать в другую функцию. Записывается в фигурных скобках: сначала параметры и возвращаемый тип, затем слово in, а за ним тело.
Swift позволяет сокращать замыкания шаг за шагом: он выводит типы из контекста, не требует return для одного выражения и разрешает обращаться к параметрам как $0, $1. Ниже одна и та же сортировка записана четыре раза, всё короче и короче:
let double = { (x: Int) -> Int in
return x * 2
}
print(double(5))
let numbers = [5, 2, 9, 1]
print(numbers.sorted(by: { (a: Int, b: Int) -> Bool in
return a > b
}))
print(numbers.sorted(by: { a, b in a > b }))
print(numbers.sorted { $0 > $1 })
print(numbers.sorted(by: >))10 [9, 5, 2, 1] [9, 5, 2, 1] [9, 5, 2, 1] [9, 5, 2, 1]
Замыкания в конце вызова
Если замыкание — последний аргумент функции, его можно написать после скобок — это называется замыканием в конце вызова (trailing closure). Именно так записаны numbers.sorted { $0 > $1 } и prices.map { $0 * 2 }. Можно написать и свою функцию, принимающую замыкание; тип её параметра — функциональный, например () -> Void.
func repeatTask(times: Int, task: () -> Void) {
for _ in 1...times {
task()
}
}
repeatTask(times: 3) {
print("Hip hip hooray!")
}
func apply(_ value: Int, _ operation: (Int) -> Int) -> Int {
operation(value)
}
func triple(_ x: Int) -> Int {
x * 3
}
print(apply(4) { $0 + 10 })
print(apply(4, triple))Hip hip hooray! Hip hip hooray! Hip hip hooray! 14 12
Замыкания запоминают переменные из того места, где они были созданы (по-английски capture — «захват»). makeCounter ниже возвращает счётчик, который при каждом вызове увеличивается на единицу: переменная count продолжает жить внутри замыкания даже после завершения функции.
func makeCounter() -> () -> Int {
var count = 0
return {
count += 1
return count
}
}
let counter = makeCounter()
print(counter())
print(counter())
print(counter())1 2 3
Главное
- Функция объявляется так:
func name(parameter: Type) -> ReturnType { ... }. - Метка аргумента пишется при вызове, имя параметра — внутри функции;
_убирает метку. - Параметр со значением по умолчанию можно не указывать при вызове.
- Замыкание — функция без имени;
$0,$1— её параметры. - Замыкание — последний аргумент — можно писать после скобок; замыкания запоминают окружающие переменные.
Проверь себя
Вопросов: 10. Каждый правильный ответ приносит XP.
func travel(from start: String, to end: String) правильный?