Diferencia entre cierre y function como argumento en swift

Tengo casi 4 años de experiencia con Objective C y un novato en Swift. Estoy tratando de entender el concepto de Swift desde la perspectiva del Objetivo C. Entonces si estoy equivocado, por favor, guíame a través 🙂

En el objective c, tenemos bloques (chunck de código que pueden ejecutarse más tarde de forma asíncrona), lo que tiene un sentido absolutamente perfecto. Pero ahora podemos pasar una function como parámetro a otra function, que puede ejecutarse más tarde, y luego también tenemos un cierre.

Según Apple, "las funciones son casos especiales de cláusulas".

Según O'Reilly, "cuando una function se transmite como un valor, lleva sus references internas a las variables externas. Eso es lo que hace que una function sea un cierre".

Entonces probé un poco para entender lo mismo 🙂

Aquí está mi cierre

override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a ni let tempNumber : Int = 5 let numbers = [1,2,3,4,5] print (numbers.map({ $0 - tempNumber})) } 

La variable tempNumber se declara incluso antes de que se haya declarado el cierre, pero el cierre tiene acceso a la variable. Ahora, en lugar de un map, intenté usar un cierre personalizado de class como parámetro e intenté ejecutar el mismo código 🙂 Aunque ahora el cierre se está ejecutando en diferentes ámbitos, todavía tiene acceso a tempNumber.

Llegué a la conclusión de que los cierres tienen acceso a las variables y methods que se declaran en el mismo scope que el cierre por sí mismo, aunque se analiza en diferentes ámbitos.

Ahora, en lugar de pasar el cierre como parámetro, intenté pasar la function como un parámetro,

 class test { func testFunctionAsParameter(testMethod : (Int) -> Int){ let seconds = 4.0 let delay = seconds * Double(NSEC_PER_SEC) // nanoseconds per seconds let dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delay)) dispatch_after(dispatchTime, dispatch_get_main_queue(), { self.callLater(testMethod) }) } func callLater(testMethod : (Int) -> Int) -> Int { return testMethod(100) } } 

En una class diferente, creé una instancia de Test y la usé como sigue

 /* in differrent class */ override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a ni let tempAge : Int = 5 func test2(val : Int) -> Int { return val - tempAge; } let testObj = test(); print(testObj.testFunctionAsParameter(test2)) } 

Declaró una class llamada testing, que tiene un método llamado testFunctionAsParameter que a su vez llama a otro método llamado callLater y finalmente este método ejecuta la function pasada 🙂

Ahora todos estos circos, solo para asegurar que el método pasado se ejecute en diferentes ámbitos 🙂

Cuando ejecuté el código anterior 🙂 me impactó ver que aunque la function pasada como un parámetro finalmente se ejecuta en un scope diferente, todavía tiene acceso a las variables testNumber que se declaró en el mismo ámbito que la statement del método 🙂

Concluí: la statement de O'Reilly "cuando una function se transmite como un valor, lleva sus references internas a las variables externas". fue genial 🙂

Ahora mi duda es que Apple dice que las funciones son casos especiales de cláusulas. Pensé que un caso especial debe tener algo que ver con el scope 🙂 Pero para mi sorpresa, el código muestra que tanto el cierre como la function tienen acceso a variables en el scope externo.

Otra diferencia de syntax es la forma en que el cierre es diferente de la function aprobada como argumento. Ahora debe haber alguna diferencia interna, de lo contrario, Apple no habría pasado tanto time diseñándolo 🙂

Si no scope? entonces, ¿qué otra cosa es diferente en el cierre y la function? O'Reilly declara "cuando una function se pasa como un valor, lleva sus references internas a las variables externas. Eso es lo que hace que una function sea un cierre". Entonces, ¿qué está tratando de señalar? ¿Ese cierre no llevará references a variables externas? Ahora tampoco pueden estar equivocados, ¿o sí?

Me estoy volviendo loco con dos declaraciones contradictorias de Apple y O'Reilly 🙁 Por favor ayuda, ¿estoy entendiendo algo mal? Por favor, ayúdame a entender la diferencia.

De manera rápida, realmente no hay ninguna diferencia entre las funciones y los cierres. Un cierre es una function anónima (una function sin nombre). Eso es todo, aparte de las diferencias de syntax anotadas.

En Objective-C, las funciones y bloques / cierres SON diferentes.

Según su publicación, parece que tiene un conocimiento bastante completo sobre el tema y puede que simplemente se pierda en la semántica. Básicamente se networkinguce a:

 1. a closure is a closure 2. a function is a closure with a name 

Aquí hay una publicación con más detalles. Pero nuevamente, es principalmente una discusión de la semántica. La respuesta es muy simple.

¿Cuál es la diferencia entre funciones y cierres?