Funciones y Closures en Swift

Funciones-y-Closures-en-Swift

Funciones y Closures en Swift

Vamos con algo sencillo declarar funciones y closures en Swift.

Es sencillo, pero es cierto que sobre todo al principio cuesta ver algunas cosas.

Por ello en esta entrada voy a poner en claro como podemos declarar funciones y closures en Swift.

Funciones

Una función es un bloque de código autónomo que permite ejecutar cierto código.

Generalmente el uso de funciones al programar sirve para que nuestros objetos interactúen unos con otros, o bien podamos crear una lógica para con ellos.

En Swift podemos declarar funciones a través de la palabra reservada func.

Podemos declarar una función simple de este modo:

func miFuncion ( ) {

}

La función declarada anteriormente no hace absolutamente nada, pero es una función.

Podemos pasar parámetros a una función, lo haremos dentro de los paréntesis, daremos un nombre y un tipo para cada uno de los parámetros que declaremos separados por comas.

func miFuncionConParametros ( nombre: String, apellidos: String, edad: Int ) {

}

Una función además puede tener un valor de retorno, sabremos que una función debe devolver algo por que encontraremos el símbolo -> después de los paréntesis, así declaramos una función con parámetros:

func miFuncionConParametrosQueDevuelveAlgo ( nombre: String, apellidos: String, edad: Int ) -> String {

return «miString»

}

Venga, vamos a avivar un poco el fuego.

Podemos pasar una función como argumento de otra función, sería algo como esto:

func miFuncionDos ( otraFuncion: (Int, String) -> String ){

var resultado = otraFuncion (10, «Sergio»)

}

Observa como el simbolo -> aparece antes de cerrar el paréntesis, es decir que la función: miFuncionDos no retorna nada, pero tiene un parámetro que es otra función de tipo: (Int, String) -> String.

Voy a crear una función que pueda usar como parámetro cuándo llame a miFuncionDos:

func funcionDentro (age: Int, name: String) -> String {

return «age: \(age) name: \(name)»

}

Entonces para llamar a miFuncionDos haría algo como esto:

miFuncionDos (funcionDentro)

Por lo tanto, podemos establecer funciones que requieran otras funciones como parámetros de entrada, así mismo podemos asignar funciones a variables, etc.

Closures

Las closures no son más que funciones «especiales».

Cuándo una función en vez de comenzar con la palabra reservada func incorpora unas llaves { } entonces se denomina función de cierre o closure.

Su sintaxis generalmente es la siguiente:

{ (parámetros) -> tipo de retorno in declaración del bloque }

Las closures son como los bloques de Objective-C o C.

Comparten con los bloques que pueden capturar el contexto léxico de su entorno.

Tomando como ejemplo la función anterior, la que recibía otra función como parámetro, podría llamar a esta función con una closure de este modo:

miFuncionDos ( { (age: Int, name: String) -> String in

return «age: \(age) name: \(name)»

} )

Fíjate como al pasarle el parámetro, en vez de pasarle una función con los tipos requeridos, le paso una closure, o función de cierre.

La llave de apertura { indica el inicio de la closure, y dentro de los paréntesis estarían los parámetros, por otra parte, después del símbolo -> estaría el valor que retorna la closure, después de la palabra reservada in definimos la implementación, para finalizar cierro la llave } y cierro el paréntesis para indicar el final del argumento o parámetro requerido para llamar a la función.

No es la única forma en que podemos usar una closure, pues al igual que las funciones, su uso es muy variado.

Resumiendo

Las closures son un tipo especial de funciones.

Tienen muchas cosas en común con los bloques de Objective-C.

Podemos usar closures de muchas formas, en el ejemplo hemos usado una closure como argumento para llamar a una función.

Que sí, que sí, que estos de Apple han pensado en todo, llevan desde el año 2010 dándole vueltas a Swift, y venga que dale, y venga que esto otro, que ahora no admitimos valores a nil, que ahora ponemos los optionals, por lo tanto, que podemos usar funciones y closures de muchas formas.

Vale, Sergio, no me he enterado de nada

No te creo.

Pero bueno, quizá tengas dudas con las closures.

Voy a intentar poner otro ejemplo para que veas la diferencia entre una función y una closure.

Imagina que quiero crear una función que calcule en cuadrado de un número.

Mediante una función simple lo podría hacer de esta forma:

func cuadradoDeUnNumero (numero :Int) -> Int {

return numero*numero

}

Dónde el nombre de la función sería cuadradoDeUnNumero, esta función requiere un parámetro de tipo Int, es decir un número entero, el nombre del parámetro es numero, además esta función devuelve un tipo de dato Int, ese decir que cuándo se llame a esta función, devolverá un numero entero, en este caso devuelve el parámetro recibido multiplicado por el propio parámetro de entrada, obteniendo así el cuadrado de un numero.

Cuándo yo quiera llamar a la función cuadradoDeUnNumero debería llamar a la función y pasarle un número entero como parámetro, esto lo haría así:

cuadradoDeUnNumero ( 5 )

Aunque también podría pasarle algo calculado como:

cuadradoDeUnNumero ( 3+2 )

En cualquiera de los casos debería arrojar un resultado de 25, y es lo que debería verse en la consola de depuración o PlayGround.

Bien, ahora vamos a hacer lo mismo pero con una closure o función de cierre.

Cómo he dicho antes, hay muchas formas de usar una closure, antes la usamos como argumento de una función, ahora vamos a usar una closure como valor de una variable, es decir voy a usar una closure y asignar el resultado de esta closure para calcular el cuadrado de un número.

Fíjate:

var cuadradoDeUnNumeroConClosure = {

(numero: Int) -> Int in

return numero*numero

}

Igual que antes podríamos llamar a mi variable junto con un número entero para que nos devuelva el cuadrado de ese número.

Escribiríamos algo así:

cuadradoDeUnNumeroConClosure ( 5 )

Pues esto es todo, desde luego que es un primer acercamiento, y en ningún caso he pretendido sentar cátedra con esta entrada, pero ojo, estás ante un post de más de 1.000 palabras, que no está nada mal 😉 así que si has llegado hasta aquí: ¡Enhorabuena!

Y por supuesto, si tienes alguna duda, déjame un comentario. 🙂

About The Author
iOS Developer & Instructor at CFE Apps. Enseño a crear aplicaciones iOS a todo el que quiera aprender.

13 Comments

  • Marques 27/02/2015 @ 19:55

    Me encanta como has explicado las closures ya lo entiendo bien jajajaja que me estaba volviendo loco

    • Sergio Becerril 01/03/2015 @ 22:23

      Muchas Gracias Crack, intento poner algo de luz ante tanta oscuridad para eruditos, je je je.

      Un abrazo.
      Sergio Becerril

  • Eduardo Debernardi 12/06/2015 @ 19:04

    Hola muy buenas reseñas amigo.

    Tengo una super duda, quiero hacer un web service desde un archivo php a mi app en xcode con swift, quiero obtener todos los datos, y luego mostrarlos en un collectionview, pero por mas que veo tutoriales no lo logro entender, tu podrias explicarme un poco como es el procedimiento

    de antemano muchas gracias

    • Sergio Becerril 14/06/2015 @ 13:02

      Hola Eduardo,

      No tienes una super duda, tienes muchas super dudas, imposible resolverlas en un comentario de un Blog.

      Aquí puedes descargar un ejemplo de como usar CollectionView.

      La clase UICollectionView tiene un método delegado que es cellForItemAtIndexPath: aquí es dónde deberías «pintar» lo que te devuelva el servidor, que podría ser un archivo JSON.

      Para parsear un JSON puedes usar la clase NSJsonSerialization.

      Si quieres puedes escribirme a: cfeapps@gmail.com dónde podré darte presupuesto de mi servicio de Consultoría, y así poder resolver todas tus dudas en condiciones 😉

      Un abrazo.
      Sergio Becerril

  • manuel 16/07/2015 @ 15:44

    hola, buen post … muy claro… me recuerda las distintas formas de programar en javascript .

    amigo tengo una duda… y no se trata de código…
    mas bien, ando iniciando en el desarrollo en ios y swift se me hace genial , relativamente fácil, pero tengo la intención de dividir mi código en distintos archivos .swift (cada archivo una clase distinta , digo por comodidad), el problema es que por alguna razón no puedo importar el modulo creado , en el viewcontroller.

    ¿cómo puedo importar una clase que esta en un archivo distinto (en el mismo proyecto) al viewcontroller.swift?… gracias

    • Sergio Becerril 17/07/2015 @ 00:45

      Hola Manuel,

      Gracias por tus palabras.

      Respecto a importar las clases en Swift, no es necesario, simplemente tienes que crear una variable o una constante del tipo de tu clase.

      No es cómo en Objective-C que tenías que estar importando la cabecera de la clase para acceder a sus propiedades y métodos.

      No sé que versión de Swift estás usando, ni siquiera sé si este es tu problema, si no he podido ayudarte dímelo, pues quizá no he entendido tu problema.

      Gracias por visitar mi Blog, y sobre todo por comentar 😉

      Un abrazo.
      Sergio Becerril

  • CARMEN 16/03/2016 @ 10:20

    Una pregunta, me dejaron un trabajo donde debo ingresar mis palabras en un archivo y de ese archivo leer las palabras desde otro pero lo que eh encontrado no me funciona

    • Sergio Becerril 16/04/2016 @ 13:05

      Hola Carmen,

      tu consulta es muy genérica, además no puedo ayudarte a crear lo que no se que quieres en el comentario de un Blog.

      Gracias por visitar mi Blog y por comentar.

      Un abrazo.
      Sergio Becerril

  • Juan Carlos 06/05/2016 @ 09:47

    Muy buenas explicaciones.
    Tengo una pregunta…¿como puedo usar una función como parámetro?

    es decir tengo la función: func suma(x: Int) -> Int, por ejemplo

    como defino otra función para que la pueda llamar de la siguiente manera:

    func prodedimientoImportante(parametros…, funcion) -> [Int]

    siendo la llamada: prodedimientoImportante(parametros…, suma)

    muchas gracias

  • Felipe Hernández Palafox 03/09/2016 @ 16:45

    Estimado Setgio antes que nada muchas gracias por proporcionarnos esta informacion lo cual nos ayuda mucho , tengo una duda sobre este tema la sintaxis de un closure en objective-c como seria sobre el ejemplo que empleaste?.

    • Sergio Becerril 04/09/2016 @ 14:57

      Hola Felipe,

      No hay closures en Objective-C, es un concepto exclusivo de Swift.

      En Objective-C lo que más se asemeja son los bloques, te recomiendo hacer una búsqueda en google: «bloques en Objective-C» para saber más sobre esto.

      Muchas gracias por visitar el blog y por comentar 😉

      Un abrazo.
      Sergio Becerril

      • Felipe Hernández Palafox 04/09/2016 @ 15:39

        Muchas gracias Sergio!! Saludos estoy a punto de comprar tu libro de swift espero que me llegue pronto!!! Saludos.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.