Функции
Функции являются автономными блоками кода, выполняющими определенную задачу. Вы даете функции имя, идентифицирующее то, что это делает, и это имя используется для «вызывания» функции для выполнения ее задачи при необходимости.
Объединенный синтаксис функций Swift достаточно гибок для выражения чего-либо от простой функции C-стиля без названий параметра к сложному методу Стиля Objective C с локальными и внешними названиями параметра для каждого параметра. Параметры могут обеспечить значения по умолчанию для упрощения вызовов функции и могут быть переданы как изменяемые параметры, изменяющие переданную переменную, как только функция завершила свое выполнение.
Каждая функция в Swift имеет тип, состоя из типов параметра функции и типа возврата. Можно использовать этот тип как любой другой тип в Swift, упрощающем передавать функции как параметры к другим функциям и возвращать функции из функций. Функции могут также быть записаны в других функциях для инкапсуляции полезной функциональности в объеме вложенной функции.
Определение и вызывание функций
При определении функции можно дополнительно определить один или несколько именованные, введенные значения, которые функция принимает как ввод (известный как параметры), и/или тип имеющий значение, который функция будет пасовать назад, как выведено, когда это будет сделано (известный как его тип возврата).
Каждая функция имеет имя функции, описывающее задачу, которую выполняет функция. Для использования функции Вы «вызываете» ту функцию с ее именем и передаете ее входные значения (известный как параметры), которые соответствуют типы параметров функции. Параметры функции должны всегда быть предоставлены в том же порядке как список параметров функции.
Функция в примере ниже вызвана sayHello
, потому что это - то, что это делает — это берет имя лица, как введено и возвращает приветствие для того лица. Для выполнения этого Вы определяете входной параметр того — a String
значение вызывают personName
— и тип возврата String
, который будет содержать приветствие для того лица:
func sayHello(personName: String) -> String {
let greeting = "Hello, " + personName + "!"
return greeting
}
Вся эта информация свертывается в определение функции, снабжающееся префиксом func
ключевое слово. Вы указываете тип возврата функции со стрелкой возврата ->
(дефис, сопровождаемый правой угловой скобкой), который сопровождается именем типа для возврата.
Определение описывает то, что делает функция, что это ожидает получать, и что это возвращает, когда это сделано. Определение упрощает для функции быть вызванным однозначно откуда-либо в Вашем коде:
println(sayHello("Anna"))
// prints "Hello, Anna!"
println(sayHello("Brian"))
// prints "Hello, Brian!"
Вы вызываете sayHello
функция путем передачи его a String
значение аргумента в круглых скобках, такой как sayHello("Anna")
. Поскольку функция возвращает a String
значение, sayHello
может быть обернут в вызов к println
функционируйте, чтобы распечатать ту строку и видеть ее возвращаемое значение, как показано выше.
Организация sayHello
функция запускается путем определения нового String
постоянный вызванный greeting
и установка его к простому приветствию обменивается сообщениями для personName
. Это приветствие тогда пасуется назад из функции с помощью return
ключевое слово. Как только return greeting
вызывается, функция заканчивает свое выполнение и возвращает текущую стоимость greeting
.
Можно вызвать sayHello
функционируйте многократно с различными входными значениями. Пример выше шоу, что происходит, если его вызывают с входным значением "Anna"
, и входное значение "Brian"
. Функция возвращает адаптированное приветствие в каждом случае.
Для упрощения организации этой функции объедините создание сообщения и оператор возврата в одну строку:
func sayHelloAgain(personName: String) -> String {
return "Hello again, " + personName + "!"
}
println(sayHelloAgain("Anna"))
// prints "Hello again, Anna!"
Параметры функции и возвращаемые значения
Параметры функции и возвращаемые значения чрезвычайно гибки в Swift. Можно определить что-либо от простой служебной функции с единственным параметром без имени к комплексной функции с выразительными названиями параметра и различными опциями параметра.
Многократные входные параметры
Функции могут иметь многократные входные параметры, записанные в круглых скобках функции, разделенных запятыми.
Эта функция берет запуск и индекс конца для полуоткрытого диапазона, и выясняет, сколько элементов диапазон содержит:
func halfOpenRangeLength(start: Int, end: Int) -> Int {
return end - start
}
println(halfOpenRangeLength(1, 10))
// prints "9"
Функции без параметров
Функции не требуются, чтобы определять входные параметры. Вот функция без входных параметров, всегда возвращающая то же String
обменивайтесь сообщениями каждый раз, когда это вызывают:
func sayHelloWorld() -> String {
return "hello, world"
}
println(sayHelloWorld())
// prints "hello, world"
Для функционального определения все еще нужны круглые скобки после имени функции, даже при том, что это не берет параметров. Когда функция вызвана, имя функции также сопровождается пустой парой круглых скобок.
Функции без возвращаемых значений
Функции не требуются, чтобы определять тип возврата. Вот версия sayHello
функция, вызванная sayGoodbye
, который распечатывает его собственное String
значение вместо того, чтобы возвратить его:
func sayGoodbye(personName: String) {
println("Goodbye, \(personName)!")
}
sayGoodbye("Dave")
// prints "Goodbye, Dave!"
Поскольку это не должно возвращать значение, определение функции не включает стрелку возврата (->
) или тип возврата.
Возвращаемое значение функции может быть проигнорировано, когда его вызывают:
func printAndCount(stringToPrint: String) -> Int {
println(stringToPrint)
return count(stringToPrint)
}
func printWithoutCounting(stringToPrint: String) {
printAndCount(stringToPrint)
}
printAndCount("hello, world")
// prints "hello, world" and returns a value of 12
printWithoutCounting("hello, world")
// prints "hello, world" but does not return a value
Первая функция, printAndCount
, распечатывает строку, и затем возвращает ее счетчик символов как Int
. Вторая функция, printWithoutCounting
, вызывает первую функцию, но игнорирует ее возвращаемое значение. Когда вторая функция вызвана, сообщение все еще распечатано первой функцией, но не используется возвращенное значение.
Функции с многократными возвращаемыми значениями
Можно использовать тип «кортеж» в качестве типа возврата для функции для возврата многократных значений как части одного составного возвращаемого значения.
Пример ниже определяет вызванную функцию minMax
, который находит самые маленькие и наибольшие числа в массиве Int
значения:
func minMax(array: [Int]) -> (min: Int, max: Int) {
var currentMin = array[0]
var currentMax = array[0]
for value in array[1..<array.count] {
if value < currentMin {
currentMin = value
} else if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
minMax
функционируйте возвращает кортеж, содержащий два Int
значения. Эти значения маркируются min
и max
так, чтобы к ним можно было получить доступ по имени при запросах возвращаемого значения функции.
Организация minMax
функция запускается путем установки двух рабочих вызванных переменных currentMin
и currentMax
к значению первого целого числа в массиве. Функция тогда выполняет итерации по остающимся значениям в массиве и проверяет каждое значение, чтобы видеть, меньше ли это или больше, чем значения currentMin
и currentMax
соответственно. Наконец, полные минимальные и максимальные значения возвращаются как кортеж два Int
значения.
Поскольку задействованные значения кортежа называют как часть типа возврата функции, к ним можно получить доступ с точечным синтаксисом для получения минимальных и максимальных найденных значений:
let bounds = minMax([8, -6, 2, 109, 3, 71])
println("min is \(bounds.min) and max is \(bounds.max)")
// prints "min is -6 and max is 109"
Обратите внимание на то, что элементы кортежа не должны называть в точке, что кортеж возвращается из функции, потому что их имена уже указаны как часть типа возврата функции.
Дополнительные типы возврата кортежа
Если тип «кортеж», который будет возвращен из функции, имеет потенциал, чтобы не иметь “никакого значения” для всего кортежа, можно использовать дополнительный тип возврата кортежа для отражения факта, что весь кортеж может быть nil
. Вы пишете дополнительный тип возврата кортежа путем размещения вопросительного знака после закрывающей скобки типа «кортеж», такой как (Int, Int)?
или (String, Int, Bool)?
.
minMax
функция выше возвращает кортеж, содержащий два Int
значения. Однако функция не выполняет проверок безопасности на массиве, это передается. Если array
параметр содержит пустой массив, minMax
функция, как определено выше, инициирует ошибку периода выполнения при попытке получить доступ array[0]
.
Для обработки этого сценария «пустого массива» безопасно запишите minMax
функция с дополнительным возвратом кортежа вводит и возвращает значение nil
когда массив пуст:
func minMax(array: [Int]) -> (min: Int, max: Int)? {
if array.isEmpty { return nil }
var currentMin = array[0]
var currentMax = array[0]
for value in array[1..<array.count] {
if value < currentMin {
currentMin = value
} else if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
Можно использовать дополнительную привязку, чтобы проверить ли эта версия minMax
функционируйте возвращает фактическое значение кортежа или nil
:
if let bounds = minMax([8, -6, 2, 109, 3, 71]) {
println("min is \(bounds.min) and max is \(bounds.max)")
}
// prints "min is -6 and max is 109"
Имена параметров функции
Все вышеупомянутые функции определяют названия параметра для их параметров:
func someFunction(parameterName: Int) {
// function body goes here, and can use parameterName
// to refer to the argument value for that parameter
}
Однако эти названия параметра только используются в организации самой функции и не могут использоваться при вызывании функции. Эти виды названий параметра известны как локальные названия параметра, потому что они только доступны для использования в организации функции.
Внешние названия параметра
Иногда полезно назвать каждый параметр, когда Вы вызываете функцию, для указания цели каждого параметра Вы передаете функции.
Если Вы хотите, чтобы пользователи Вашей функции обеспечили названия параметра, когда они вызывают Вашу функцию, определяют внешнее название параметра для каждого параметра, в дополнение к локальному названию параметра. Вы пишете внешнее название параметра перед локальным названием параметра, которое оно поддерживает, разделенный пространством:
func someFunction(externalParameterName localParameterName: Int) {
// function body goes here, and can use localParameterName
// to refer to the argument value for that parameter
}
Как пример, рассмотрите следующую функцию, присоединяющуюся к двум строкам путем вставки третьей строки «столяра» между ними:
func join(s1: String, s2: String, joiner: String) -> String {
return s1 + joiner + s2
}
Когда Вы вызываете эту функцию, цель трех строк, которые Вы передаете функции, неясна:
join("hello", "world", ", ")
// returns "hello, world"
Сделать цель из них String
расчетная организация значений, определите внешние названия параметра для каждого join
параметр функции:
func join(string s1: String, toString s2: String, withJoiner joiner: String)
-> String {
return s1 + joiner + s2
}
В этой версии join
функция, первый параметр имеет внешнее имя string
и локальное имя s1
; второй параметр имеет внешнее имя toString
и локальное имя s2
; и третий параметр имеет внешнее имя withJoiner
и локальное имя joiner
.
Можно теперь использовать эти внешние названия параметра для вызывания функции однозначно:
join(string: "hello", toString: "world", withJoiner: ", ")
// returns "hello, world"
Использование внешних названий параметра включает эту вторую версию join
функция, которую вызовут выразительным, подобным предложению способом пользователи функции, все еще обеспечивая тело функции, которое читаемо и ясно в намерении.
Сократите внешние названия параметра
Если Вы хотите обеспечить внешнее название параметра для параметра функции, и локальное название параметра уже является надлежащим именем к использованию, Вы не должны написать то же имя дважды для того параметра. Вместо этого напишите имя один раз и снабдите префиксом имя символ хеша (#
). Это говорит Свифту использовать то имя и в качестве локального названия параметра и в качестве внешнего названия параметра.
Этот пример определяет вызванную функцию containsCharacter
, который определяет внешние названия параметра для обоих из его параметров путем размещения символа хеша перед их локальными названиями параметра:
func containsCharacter(#string: String, #characterToFind: Character) -> Bool {
for character in string {
if character == characterToFind {
return true
}
}
return false
}
Выбор этой функции названий параметра делает для ясного, читаемого тела функции, также позволяя функции быть вызванным без неоднозначности:
let containsAVee = containsCharacter(string: "aardvark", characterToFind: "v")
// containsAVee equals true, because "aardvark" contains a "v"
Значения параметров по умолчанию
Можно определить значение по умолчанию для любого параметра как часть определения функции. Если значение по умолчанию определяется, можно опустить тот параметр при вызывании функции.
Вот версия join
функция от ранее, обеспечивающая значение по умолчанию для joiner
параметр:
func join(string s1: String, toString s2: String,
withJoiner joiner: String = " ") -> String {
return s1 + joiner + s2
}
Если строковое значение для joiner
предоставлен когда join
функция вызвана, то строковое значение используется для присоединения к двум строкам вместе, как прежде:
join(string: "hello", toString: "world", withJoiner: "-")
// returns "hello-world"
Однако, если никакое значение joiner
предоставлен, когда функция вызвана, значение по умолчанию одиночного пробела (" "
) используется вместо этого:
join(string: "hello", toString: "world")
// returns "hello world"
Внешние имена для параметров со значениями по умолчанию
В большинстве случаев полезно обеспечить (и поэтому потребовать) внешнее имя для любого параметра со значением по умолчанию. Это гарантирует, что параметр за тот параметр ясен в цели, если значение предоставлено, когда вызвана функция.
Для создания этого процесса проще Swift обеспечивает автоматическое внешнее имя для любого параметра, имеющего значение по умолчанию. Автоматическое внешнее имя совпадает с локальным именем, как будто Вы записали символ хеша перед локальным именем в Вашем коде.
Вот версия join
функция от ранее, не обеспечивающая внешние имена ни для одного из ее параметров, но все еще обеспечивающая значение по умолчанию для ее joiner
параметр:
func join(s1: String, s2: String, joiner: String = " ") -> String {
return s1 + joiner + s2
}
В этом случае Swift автоматически обеспечивает внешнее название параметра для joiner
параметр. Внешнее имя должно поэтому быть предоставлено при вызывании функции, ясно давании понять цели параметра и однозначный:
join("hello", "world", joiner: "-")
// returns "hello-world"
Параметры Variadic
variadic параметр принимает нуль или больше значений указанного типа. Вы используете variadic параметр, чтобы указать, что параметр может быть передан переменное число входных значений, когда вызвана функция. Запишите variadic параметры путем вставки трех символов точки (...
) после имени типа параметра.
Значения, переданные variadic параметру, сделаны доступными в организации функции как массив надлежащего типа. Например, variadic параметр с именем numbers
и тип Double...
сделан доступным в организации функции как постоянный вызванный массив numbers
из типа [Double]
.
Пример ниже вычисляет среднее арифметическое (также известный как среднее число) для списка чисел любой длины:
func arithmeticMean(numbers: Double...) -> Double {
var total: Double = 0
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
// returns 3.0, which is the arithmetic mean of these five numbers
arithmeticMean(3, 8.25, 18.75)
// returns 10.0, which is the arithmetic mean of these three numbers
Постоянные и переменные параметры
Параметры функции являются константами по умолчанию. Попытка изменить значение параметра функции из организации той функции приводит к ошибке времени компиляции. Это означает, что Вы не можете изменить значение параметра по ошибке.
Однако иногда для функции полезно иметь переменную копию значения параметра для работы с. Можно избежать определять новую переменную сами в функции путем указания одного или более параметров как переменные параметры вместо этого. Переменные параметры доступны как переменные, а не как константы и дают новую модифицируемую копию значения параметра для Вашей функции для работы с.
Определите переменные параметры путем добавления префикса названия параметра ключевое слово var
:
func alignRight(var string: String, count: Int, pad: Character) -> String {
let amountToPad = count - count(string)
if amountToPad < 1 {
return string
}
let padString = String(pad)
for _ in 1...amountToPad {
string = padString + string
}
return string
}
let originalString = "hello"
let paddedString = alignRight(originalString, 10, "-")
// paddedString is equal to "-----hello"
// originalString is still equal to "hello"
Этот пример определяет новую вызванную функцию alignRight
, который выравнивает входную строку к правому краю более длительной выводимой строки. Любое пространство слева заполнено указанным дополнительным символом. В этом примере, строке "hello"
преобразовывается в строку "-----hello"
.
alignRight
функция определяет входной параметр string
быть переменным параметром. Это означает это string
теперь доступно как локальная переменная, инициализированная с переданным - в строковом значении, и может управляться в организации функции.
Функция запускается путем разработки, налево от скольких должны быть добавлены символы string
чтобы к выравниванию по правому краю это в полной строке. Это значение сохранено в локальной вызванной константе amountToPad
. Если никакое дополнение не необходимо (т.е. если amountToPad
меньше, чем 1
), функция просто возвращает входное значение string
без любого дополнения.
Иначе, функция создает новый временный файл String
постоянный вызванный padString
, инициализированный с pad
символ, и добавляет amountToPad
копии padString
налево от существующей строки. (A String
значение не может быть прибавлено к a Character
значение, и таким образом, padString
постоянный используется, чтобы гарантировать что обе стороны +
оператор String
значения.)
Изменяемые параметры
Переменные параметры, как описано выше, могут только быть изменены в самой функции. Если Вы хотите, чтобы функция изменила значение параметра, и Вы хотите, чтобы те изменения сохранились после того, как вызов функции закончился, определите тот параметр как изменяемый параметр вместо этого.
Вы пишете изменяемый параметр путем размещения inout
ключевое слово в начале его определения параметра. Изменяемый параметр имеет значение, передающееся в функции, изменяющееся функцией и пасующееся назад из функции для замены исходного значения.
Можно только передать переменную как параметр за изменяемый параметр. Вы не можете передать константу или литеральное значение как параметр, потому что не могут быть изменены константы и литералы. Вы помещаете амперсанд (&
) непосредственно перед именем переменной, когда Вы передаете его как параметр параметру, являющемуся одновременно входным и выходным, чтобы указать, что это может быть изменено функцией.
Вот пример вызванной функции swapTwoInts
, который имеет два в - целочисленные вызванные параметры a
и b
:
func swapTwoInts(inout a: Int, inout b: Int) {
let temporaryA = a
a = b
b = temporaryA
}
swapTwoInts
функционируйте просто подкачивает значение b
в a
, и значение a
в b
. Функция выполняет эту подкачку путем хранения значения a
во временной вызванной константе temporaryA
, присвоение значения b
к a
, и затем присвоение temporaryA
к b
.
Можно вызвать swapTwoInts
функция с двумя переменными типа Int
подкачивать их значения. Обратите внимание на то, что имена someInt
и anotherInt
снабжаются префиксом амперсанд, когда они передаются swapTwoInts
функция:
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
println("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// prints "someInt is now 107, and anotherInt is now 3"
Пример выше шоу, что исходные значения someInt
и anotherInt
изменяются swapTwoInts
функция, даже при том, что они были первоначально определены за пределами функции.
Функциональные типы
Каждая функция имеет определенный функциональный тип, составленный из типов параметра и типа возврата функции.
Например:
func addTwoInts(a: Int, b: Int) -> Int {
return a + b
}
func multiplyTwoInts(a: Int, b: Int) -> Int {
return a * b
}
Этот пример определяет две простых вызванные математических функции addTwoInts
и multiplyTwoInts
. Эти функции каждый берет два Int
значения и возврат Int
значение, которое является результатом выполнения надлежащей математической операции.
Тип обеих из этих функций (Int, Int) -> Int
. Это может быть считано как:
“Функциональный тип, имеющий два параметра, оба из типа Int
, и это возвращает значение типа Int
.”
Вот другой пример для функции без параметров или возвращаемого значения:
func printHelloWorld() {
println("hello, world")
}
Тип этой функции () -> ()
, или “функция, не имеющая никаких параметров и возвратов Void
.” Функции, не указывающие возвращаемое значение всегда, возвращаются Void
, который эквивалентен пустому кортежу в Swift, показанном как ()
.
Используя функциональные типы
Вы используете функциональные типы точно так же, как любые другие типы в Swift. Например, можно определить константу или переменный, чтобы иметь функциональный тип и присвоить надлежащую функцию той переменной:
var mathFunction: (Int, Int) -> Int = addTwoInts
Это может быть считано как:
“Определите вызванную переменную mathFunction
, который имеет тип ‘функции, берущей два Int
значения и возвраты Int
значение’. Установите эту новую переменную для обращения к вызванной функции addTwoInts
.”
addTwoInts
функция имеет тот же тип как mathFunction
переменная, и таким образом, это присвоение позволяется средством проверки типа Swift.
Можно теперь вызвать присвоенную функцию с именем mathFunction
:
println("Result: \(mathFunction(2, 3))")
// prints "Result: 5"
Различная функция с тем же типом соответствия может быть присвоена той же переменной, таким же образом что касается нефункциональных типов:
mathFunction = multiplyTwoInts
println("Result: \(mathFunction(2, 3))")
// prints "Result: 6"
Как с любым другим типом, можно предоставить Swift право выводить функциональный тип при присвоении функции константе или переменный:
let anotherMathFunction = addTwoInts
// anotherMathFunction is inferred to be of type (Int, Int) -> Int
Функциональные типы как типы параметра
Можно использовать функциональный тип такой как (Int, Int) -> Int
как тип параметра для другой функции. Когда функция вызвана, это позволяет Вам оставить некоторые аспекты реализации функции для вызывающей стороны функции для обеспечения.
Вот пример для печати результатов математических функций сверху:
func printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int) {
println("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5)
// prints "Result: 8"
Этот пример определяет вызванную функцию printMathResult
, который имеет три параметра. Первый параметр вызывают mathFunction
, и имеет тип (Int, Int) -> Int
. Можно передать любую функцию того типа как параметр за этот первый параметр. Вторые и третьи параметры вызывают a
и b
, и имеют оба тип Int
. Они используются в качестве этих двух входных значений для предоставленной математической функции.
Когда printMathResult
вызывается, это передается addTwoInts
функция и целочисленные значения 3
и 5
. Это вызывает предоставленную функцию со значениями 3
и 5
, и распечатывает результат 8
.
Роль printMathResult
должен распечатать результат вызова к математической функции надлежащего типа. Не имеет значения, что фактически делает реализация той функции — имеет значение только, что функция имеет корректный тип. Это включает printMathResult
вручить от части его функциональности к вызывающей стороне функции безопасным с точки зрения типов способом.
Функциональные типы как типы возврата
Можно использовать функциональный тип в качестве типа возврата другой функции. Вы делаете это путем записи полного функционального типа сразу после стрелки возврата (->
) из функции возврата.
Следующий пример определяет две простых вызванные функции stepForward
и stepBackward
. stepForward
функционируйте возвращает значение еще одно, чем его входное значение, и stepBackward
функционируйте возвращает значение меньше, чем его входное значение. Обе функции имеют тип (Int) -> Int
:
func stepForward(input: Int) -> Int {
return input + 1
}
func stepBackward(input: Int) -> Int {
return input - 1
}
Вот вызванная функция chooseStepFunction
, чей тип возврата является “функцией типа (Int) -> Int
”. chooseStepFunction
возвраты stepForward
функционируйте или stepBackward
функционируйте на основе вызванного булева параметра backwards
:
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
return backwards ? stepBackward : stepForward
}
Можно теперь использовать chooseStepFunction
получить функцию, которая продвинется в одно направление или другой:
var currentValue = 3
let moveNearerToZero = chooseStepFunction(currentValue > 0)
// moveNearerToZero now refers to the stepBackward() function
Предыдущий пример определяет, необходим ли положительный или отрицательный шаг для перемещения вызванной переменной currentValue
прогрессивно ближе обнулять. currentValue
имеет начальное значение 3
, что означает это currentValue > 0
возвраты true
, порождение chooseStepFunction
возвратиться stepBackward
функция. Ссылка на возвращенную функцию сохранена в вызванной константе moveNearerToZero
.
Теперь, когда moveNearerToZero
относится к корректной функции, она может использоваться для подсчета для обнуления:
println("Counting to zero:")
// Counting to zero:
while currentValue != 0 {
println("\(currentValue)... ")
currentValue = moveNearerToZero(currentValue)
}
println("zero!")
// 3...
// 2...
// 1...
// zero!
Вложенные функции
Все функции, с которыми Вы встретились до сих пор в этой главе, были примерами глобальных функций, определяющихся на глобальном уровне. Можно также определить функции в организациях других функций, известных как вложенные функции.
Вложенные функции скрыта от внешнего мира по умолчанию, но может все еще вызвать и использовать их функция включения. Функция включения может также возвратить одну из своих вложенных функций, чтобы позволить вложенной функции использоваться в другом объеме.
Можно переписать chooseStepFunction
пример выше, чтобы использовать и возвратить вложенные функции:
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
func stepForward(input: Int) -> Int { return input + 1 }
func stepBackward(input: Int) -> Int { return input - 1 }
return backwards ? stepBackward : stepForward
}
var currentValue = -4
let moveNearerToZero = chooseStepFunction(currentValue > 0)
// moveNearerToZero now refers to the nested stepForward() function
while currentValue != 0 {
println("\(currentValue)... ")
currentValue = moveNearerToZero(currentValue)
}
println("zero!")
// -4...
// -3...
// -2...
// -1...
// zero!