Видеокурсы по изучению языка программирования Swift. Подробнее

Функции и замыкания

Если вы нашли опечатку в тексте, выделите ее и нажмите CTRL + ENTER.

Чтобы объявить функцию используйте оператор func. Чтобы вызвать функцию просто напишите ее имя со списком аргументов в скобках. Используйте –> чтобы отделить имена и типы аргументов от возвращаемого типа функции.

func greet(name: String, day: String) -> String {
    return "Hello \(name), today is \(day)."
}
greet(name: "Bob", day: "Tuesday")

Задание

Удалите аргумент day. Добавьте аргумент, чтобы вставить сегодняшнее блюдо дня в приветствие.

По умолчанию функии используют имена параметров как ярлыки для их аргументов. Напишите свой собственный ярлык до имени параметра функции, или напишите знак подчеркивания (_) для того, чтобы пропустить ярлык.

func greet(_ person: String, on day: String) -> String {
    return "Hello \(person), today is \(day)."
}
greet("John", on: "Wednesday")

Используйте кортеж для создания единого составного значения, например для возвращения нескольких значений из функции. Ссылаться на элементы кортежа можно либо через имена, либо через порядковые номера

func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) {
    var min = scores[0]
    var max = scores[0]
    var sum = 0
    
    for score in scores {
        if score > max {
            max = score
        } else if score < min {
            min = score
        }
        sum += score
    }
    
    return (min, max, sum)
}
let statistics = calculateStatistics(scores: [5, 3, 100, 3, 9])
print(statistics.sum)
print(statistics.2)

Функция также может принимать переменное количество аргументов, собирая их в массив:

func sumOf(numbers: Int...) -> Int {
    var sum = 0
    for number in numbers {
        sum += number
    }
    return sum
}
sumOf()
sumOf(numbers: 42, 597, 12)

Задание

Напишите функцию, которая бы считала среднее значение его аргументов.

Функции могут быть вложенными. Вложенные функции имеют доступ к переменным, которые были объявлены во внешней функции. Вы можете использовать вложенные функции, чтобы упорядочивать код в длинных или сложных функциях.

func returnFifteen() -> Int {
    var y = 10
    func add() {
        y += 5
    }
    add()
    return y
}
returnFifteen()

Функции - это объект первого класса. Это означает, что результатом функции может быть другая функция.

func makeIncrementer() -> ((Int) -> Int) {
    func addOne(number: Int) -> Int {
        return 1 + number
    }
    return addOne
}
var increment = makeIncrementer()
increment(7)

Функция может принимать другую функцию в качестве аргумента.

func hasAnyMatches(list: [Int], condition: (Int) -> Bool) -> Bool {
    for item in list {
        if condition(item) {
            return true
        }
    }
    return false
}
func lessThanTen(number: Int) -> Bool {
    return number < 10
}
var numbers = [20, 19, 7, 12]
hasAnyMatches(list: numbers, condition: lessThanTen)

Функции на самом деле - частный случай замыканий. Замыкания представляют из себя блок кода, который может быть вызван позже. Код внутри замыканий имеет доступ к таким объектам, как к переменные и функции, которые были созданы в тех же рамках, что и сами замыкания. Даже если замыкание находятся и запускается в другом блоке , вы уже видели этот пример во вложенных функциях. Вы можете написать замыкание без имени, просто обозначив код фигурными скобками и круглыми скобками ({}). Внутри скобок используйте in для разграничения аргументов и возвращаемого типа от тела замыкания.

numbers.map({
    (number: Int) -> Int in
    let result = 3 * number
    return result
})

Задание

Перепишите замыкание так, чтобы оно вернуло ноль для всех нечетных чисел.

У вас есть несколько способов для того, чтобы написать замыкание более кратко. Когда тип замыкания точно известен, например - обратный вызов делегата (callback), вы можете пропустить тип его аргументов, тип возвращаемого значения, либо и то и другое. Одиночный оператор замыкания неявно возвращает значение своего единственного выражения.

let mappedNumbers = numbers.map({ number in 3 * number })
print(mappedNumbers)

Вы можете обращаться к аргументам по номеру, вместо имени. Этот подход особенно полезен в очень коротких замыканиях. Замыкание, переданное как последний аргумент функции, может появиться непосредственно после скобок.

let sortedNumbers = numbers.sorted { $0 > $1 }
print(sortedNumbers)
Swift: 
3.0