Материал: iOS сессия ответы

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Значение по умолчанию для входного аргумента

Напомню, что все входные аргументы должны обязательно иметь значения. Ранее для этого мы указывали их при вызове функции. Но существует возможность определить значения по умолчанию, которые позволяют не указывать значения при вызове. Другими словами: если вы передали значение входного аргумента, то оно будет использовано в теле функции; если вы не передали значение аргумента, для него будет использовано значение по умолчанию. Значение по умолчанию указывается при объявлении функции в списке входных аргументов для каждого параметра отдельно.

Доработаем объявленную ранее функцию returnMessage(code:message:) таким образом, чтобы была возможность не передавать значение аргумента message. Для этого укажем значение по умолчанию (листинг 15.12).

Листинг 15.12

funcreturnMessage(code: Int, message: String = "Код - ") -> String {

varmutableMessage = message

mutableMessage += String(code)

return mutableMessage

}

returnMessage(code: 300) //"Код - 300"

Каквыможетевидеть, привызовеreturnMessage(code:message:) не передаетсязначениедляаргумента message. Это стало возможным благодаря установке значения по умолчанию "Код - " в списке входных параметров.

Внешние имена входных аргументов

Аргументы a и b функции sumTwoInt(a:b:) используются как при вызове функции, так и в ее теле. Swift позволяет указать внешние имена параметров, которые будут использоваться при вызове функции

Листинг 15.3

funcsumTwoInt(num1 a: Int, num2 b: Int){

print("Результат операции - \(a+b)")

}

sumTwoInt(num1: 10, num2: 12)

Теперь при вызове функции sumTwoInt(num1:num2:) необходимо указывать значения не для безликих a и b, а для более-менее осмысленных num1 и num2. Данный прием очень полезен, так как позволяет задать понятные и соответствующие контексту названия входных аргументов, но при этом сократить количества кода в теле, используя краткие внутренние имена. Если внешнее имя заменить на символ нижнего подчеркивания (_), то при вызове функции имя параметра вообще не потребуется указывать

Листинг 15.4

funcsumTwoInt(_ a: Int, _ b: Int){

print("Результат операции - \(a+b)")

}

sumTwoInt(10, 12)

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

31. Рекурсивный вызов функций. Безымянные функции.

показан пример инициализации замыкания в параметр closure. При этом у параметра явно указан функциональный тип (ранее в примерах он определялся неявно).

var closure: () -> () = {

print("Замыкающее выражение")

}

closure()

Консоль Замыкающее выражение

Так как данное замыкающее выражение не имеет входных параметров и возвращаемого значения, то его тип равен ()->(). Для вызова записанного в константу замыкающего выражения необходимо написать имя константы с круглыми скобками, точно так же, как мы делали это ранее. Явное указание функционального типа позволяет определить входные аргументы и тип выходного значения

32.Замыкания. Функция как замыкания

Как объясняется в документации к языку Swift, замыкания (closures) — это организованные блоки с определенным функционалом, которые могут быть переданы и использованы в коде. Согласитесь, не очень доступное объяснение. Попробуем иначе.

Замыкания (closure), или замыкающие выражения, — это сгруппированный программный код, который может быть передан в виде параметра и многократно использован. Ничего не напоминает? Если вы скажете, что в этом определении узнали функции, то будете полностью правы.

Как вы знаете, параметры предназначены для хранения информации, а функции могут выполнять определенные задачи. Говоря простым языком, с помощью замыканий вы можете поместить блок исполняемого кода в переменную или константу, свободно передавать ее и при необходимости вызывать хранящийся в ней код. Вы уже видели подобный подход при изучении функций, и в этом нет ничего странного. Дело в том, что функции — это частный случай замыканий. В общем случае замыкание (closure) может принять две формы: ‰ именованная функция; ‰ безымянная функция, определенная с помощью облегченного синтаксиса. Знакомству с именованными функциями была посвящена вся предыдущая глава. Уверен, что вы уже довольно неплохо знакомы с их возможностями.

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

Как вы уже знаете, переменная и константа могут хранить в себе ссылку на функцию. Но для того чтобы организовать это, не обязательно возвращать одну функцию из другой. Вы можете использовать специальный облегченный синтаксис, создав безымянную функцию, после чего передать ее в качестве значения в требуемый параметр. Безымянные функции не имеют имен. Они состоят только из тела, заключенного в фигурные скобки.

{ (входные_параметры) -> тип in

// тело замыкающего выражения

}

  • входные_параметры — список аргументов замыкания с указанием их имен и типов.

• Тип — тип данных значения, возвращаемого замыканием.

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

Пример

// безымянная функция в качестве значения константы

let functionInLet = {return true}

// вызываем безымянную функцию

functionInLet() // true

Константа functionInLet имеет функциональный тип () -> Bool (ничего не принимает на вход, но возвращает логическое значение) и хранит в себе тело функции. Обратите внимание, что при инициализации безымянной функции в параметр для ее вызова используется имя параметра с круглыми скобками.

33. Замыкание.Замыкающие выражение

Замыкающие выражения, являются способом написания встроенных замыканий через краткий и специализированный синтаксис. Замыкающие выражения обеспечивают несколько синтаксических оптимизаций для написания замыканий в краткой форме, без потери ясности и намерений. Примеры замыкающих выражений ниже, показывают эти оптимизации путем рассмотрения метода sorted(by:) при нескольких итерациях, каждая из которых изображает ту же функциональность в более сжатой форме.

В стандартной библиотеке Swift есть метод sorted(by:), который сортирует массив значений определенного типа, основываясь на результате сортирующего замыкания, которые вы ему передадите. После завершения процесса сортировки, метод sorted(by:) возвращает новый массив того же типа и размера как старый, с элементами в правильном порядке сортировки. Исходный массив не изменяется методом sorted(by:).

Примеры замыкающих выражений ниже используют метод sorted(by:)для сортировки массива из String значений в обратном алфавитном порядке. Вот исходный массив для сортировки:

let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]

Замыкание метода sorted(by:) принимает два аргумента одного и того же типа, что и содержимое массива, и возвращает Bool значение, которое решает поставить ли первое значение перед вторым, или после второго. Замыкание сортировки должно вернуть true, если первое значение должно быть до второго значения, и false в противном случае.

Этот пример сортирует массив из String значений, так что сортирующее замыкание должно быть функцией с типом (String, String) -> Bool.

Один из способов обеспечить сортирующее замыкание, это написать нормальную функцию нужного типа, и передать ее в качестве аргумента метода sorted(by:):

func backward(_ s1: String, _ s2: String) -> Bool {

return s1 > s2

}

var reversedNames = names.sorted(by: backward)

// reversedNames равен ["Ewa", "Daniella", "Chris", "Barry", "Alex"]

Если первая строка (s1) больше чем вторая строка (s2), функция backward(_:_:) возвращает true, что указывает, что s1 должна быть перед s2 в сортированном массиве. Для символов в строках, "больше чем" означает "появляется в алфавите позже, чем". Это означает что буква "B" "больше чем" буква "А", а строка "Tom" больше чем строка "Tim". Это делает обратную алфавитную сортировку, с "Barry" поставленным перед "Alex", и так далее.

Тем не менее, это довольно скучный способ написать то, что по сути, является функцией с одним выражением (a > b). В этом примере, было бы предпочтительнее написать сортирующее замыкание в одну строку, используя синтаксис замыкающего выражения.

Синтаксис замыкающего выражения может использовать сквозные параметры. Значения по умолчанию не могут быть переданы. Вариативные параметры могут быть использованы в любом месте в списке параметров. Кортежи также могут быть использованы как типы параметров и как типы возвращаемого значения.

34 .Замыкания. Неявное возвращение значения. Сокращенные имена параметров

Swift - Замыкания

Замыкания - это автономные блоки функциональности, которые можно передавать и использовать в вашем коде. Замыкания в Swift похожи на блоки в C и Objective-C и на лямбды в других языках программирования.

Замыкания могут захватывать и хранить ссылки на любые константы и переменные из контекста, в котором они определены. Это называется закрытием этих констант и переменных. Swift обрабатывает все управление памятью захвата для вас.

ЗАМЕТКА

Не беспокойтесь, если вы не знакомы с концепцией захвата. Это подробно объясняется ниже в разделе «Захват ценностей» .

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

  • Глобальные функции - это замыкания, которые имеют имя и не захватывают никаких значений.

  • Вложенные функции - это замыкания, которые имеют имя и могут захватывать значения из своей вмещающей функции.

  • Выражения замыканий - это безымянные замыкания, написанные в упрощенном синтаксисе, которые могут захватывать значения из окружающего контекста.

Аладыжәнекөрсетілгендейерікті параметр (айнымалынемесетұрақты)

4.18 листингінде.

Листинг 4.18

varfoo = "Текст для консоли"

print(foo)

Консоль: Текст для консоли

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

  • Вывод параметров и типов возвращаемых значений из контекста

  • Неявные возвраты от замыканий с одним выражением

  • Сокращенные имена аргументов

  • Синтаксис замыкающего замыкания