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. 🙂
13 Comments