3

Я только учусь некоторый Свифт и я пришел через раздел, что говорит о вложенности функций:Что такое преимущество вложенности функций (в общем/в Swift)

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

От here

Таким образом, если предполагаемая польза является «организовать код», почему не только имеют вложенную функцию независимо друг от друга, за пределами внешней функции? Это, для меня, кажется более организованным.

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

Любые мысли?

+2

Продолжайте читать, пока не дойдете Функции главы и тогда вы заметите пользу :) –

ответ

7

Так что, если предполагаемая выгода заключается в «организации кода», почему бы просто не иметь вложенную функцию независимо от внешней функции? Это, для меня, кажется более организованным.

О, я совершенно не согласен. Если единственное место, где требуется вторая функция, находится внутри первой функции, удерживая ее внутри первой функции, много более организованной.

примеры реальной жизни здесь: http://www.apeth.com/swiftBook/ch02.html#_function_in_function

Plus, функция в функции имеет локальное окружение в области. Код внутри вложенной функции может «видеть» локальные переменные, объявленные перед объявлением вложенной функции. Это может быть гораздо более удобным и естественным, чем передача множества параметров.

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

http://www.apeth.com/swiftBook/ch02.html#_function_returning_function

+0

хорошо, это было просто. спасибо, что выделили это! (отметит правильный ответ за 6 минут) – Jona

+0

@matt Я полностью согласен с вами; Моя единственная забота - это размер тела функции и разрыв между объявлением родительской функции и ее фактическим телом. Скажем, у нас есть 3-5 вспомогательных функций (локальных функций) внутри функции, их нужно объявить в верхней части функции; Поэтому читателю приходится прокручивать много строк, чтобы достичь реального тела; Что вы предлагаете для таких ситуаций? Должны ли мы извлечь эту функцию в качестве нового класса? – Erfan

+0

@matt Нет, я думаю, может быть, я сделал это. скриншот примера: https://www.dropbox.com/s/lzepxqxujrth4yf/Screen%20Shot%202016-09-01%20at%2010.08.11%20AM.jpg?dl=0. Я забочусь о родительском func, который здесь «convertToParams» и разрыв между его сигнатурой и его фактическим телом («MARK: convertToParams body»). Мне очень нравится выполнять функции, которые помогают функции выполнять свою работу внутри функции; но эта проблема, которую вы должны прокручивать от подписи до фактического тела, заставляет меня беспокоиться о ее читаемости. И может потребоваться еще больше функций. Какое устное предложение? – Erfan

0

ИМО, единственное отличие замыканий и вложенных функций рекурсии. Вы можете обратиться к самой функции в тело функции без трюка.

func a() { 
    func b() { 
     b() // Infinite loop! 
    } 
    b() 
} 

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

Технически это делает эталонный цикл и обычно обескуражен. Но это может быть полезно, если вы используете это с умом.

Например, объедините это с асинхронными операциями.

func spawnAsyncOp1(_ completion: @escaping() -> Void) { 
    enum Continuation { 
     case start 
     case waitForSomethingElse1 
     case retry 
     case end 
    } 
    let someResource = SomeResource() 
    func step(_ c: Continuation) { 
     switch c { 
     case .start: 
      return step(.waitForSomethingElse1) 

     case .waitForSomethingElse1: 
      DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(10), execute: { 
       let fc = (someResource.makeRandomResult() % 100 < 50) ? .end : .retry as Continuation 
       print("\(fc)") 
       return step(fc) 
      }) 

     case .retry: 
      return step(.start) 

     case .end: 
      return completion() 
     } 
    } 
    return step(.start) 
} 

Это может сделать управление ресурсами в выполнении сопрограммы более простой без явного экземпляра объекта.Ресурсы просто захватываются функцией spawnAsyncOp1 и будут выпущены, когда функция умрет.

0

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

image

Смежные вопросы