Spec-Zone .ru
спецификации, руководства, описания, API

Библиотека разработчика XCode

Разработчик

Swift язык программирования

iBook
На этой странице

Функции

Функции являются автономными блоками кода, выполняющими определенную задачу. Вы даете функции имя, идентифицирующее то, что это делает, и это имя используется для «вызывания» функции для выполнения ее задачи при необходимости.

Объединенный синтаксис функций 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!