Swift From Scratch una introducción a las funciones

Para hacer cualquier cosa en Swift, necesitas aprender los entresijos de las funciones. Las funciones son excepcionalmente poderosas y flexibles en Swift. Los conceptos básicos son simples, especialmente si ha trabajado con otros lenguajes de programación anteriormente. Pero debido a la sintaxis flexible de Swift, las funciones pueden llegar a ser confusas si no está familiarizado con lo básico. 

En este artículo, nos centramos en los conceptos básicos primero. Luego continuaremos explorando la sintaxis más compleja y los casos de uso en el próximo artículo. Es importante que no hoje los conceptos básicos, ya que son esenciales para comprender de dónde proviene el poder de una función. Empecemos por diseccionar la anatomía de una función en Swift con un ejemplo..

1. Aprender por ejemplo

Una función no es más que un bloque de código que puede ejecutarse cuando sea necesario. Veamos un ejemplo de la anatomía básica de una función Swift. Arranca Xcode y crea un nuevo parque infantil. Agregue la siguiente definición de función al patio de recreo.

func printHelloWorld () print ("Hello World!")

Una función comienza con la función palabra clave y es seguido por el nombre de la función, printHelloWorld en nuestro ejemplo Como en muchos otros idiomas, el nombre de la función va seguido de un par de paréntesis que contienen los parámetros de la función: la entrada a la función.

El cuerpo de la función está envuelto en un par de llaves. los printHelloWorld () La función contiene una sola instrucción que imprime la cadena. Hola Mundo! a la salida estándar. Así es como se ve una función básica en Swift. La sintaxis es simple, limpia y minimalista..

Puede invocar la función escribiendo el nombre de la función, seguido de un par de paréntesis.

printHelloWorld ()

2. Parámetros

Hagamos el ejemplo anterior un poco más complejo agregando parámetros a la definición de la función. Esto simplemente significa que proporcionamos a la función valores de entrada que puede usar en el cuerpo de la función. En el siguiente ejemplo, definimos la PrintMessage (mensaje :) Función que acepta un parámetro., mensaje, de tipo Cuerda.

func printMessage (message: String) print (message)

Una función puede aceptar múltiples parámetros o valores de entrada. Los parámetros están envueltos por los paréntesis que siguen al nombre de la función. El nombre del parámetro va seguido de dos puntos y el tipo del parámetro. Como recordará, esto es muy similar a declarar una variable o una constante. Simplemente dice que la mensaje parámetro es de tipo Cuerda.

En lugar de imprimir una cadena codificada como lo hicimos en el printHelloWorld () función, imprimimos el mensaje Valor del parámetro. Esto hace que la función sea flexible y más útil..

Invocar la función es muy similar a lo que vimos anteriormente. La única diferencia es que pasamos un argumento al invocar la función.

printMessage (mensaje: "¡Hola mundo!")

Tenga en cuenta que los términos parámetros y argumentos a menudo se usan indistintamente, pero hay una diferencia semántica sutil en Swift. En Swift, los parámetros son los valores especificados en la definición de la función, mientras que los argumentos son los valores que se pasan a la función cuando se invoca.

Parámetros múltiples

Como mencioné anteriormente, la sintaxis de las funciones es muy flexible, y no debería sorprenderte que es perfectamente posible pasar múltiples argumentos a una función. En el siguiente ejemplo, creamos una variación en el PrintMessage (mensaje: veces :) Función que nos permite imprimir el mensaje varias veces..

func printMessage (mensaje: String, times: Int) para i en 0 ... 

Si bien el nombre de la función es idéntico al del original PrintMessage (mensaje :) función, el tipo de función es diferente. 

Es importante que entiendas la oración anterior. Leelo de nuevo.

Cada función tiene un tipo, que consiste en los tipos de parámetros y el tipo de retorno. Vamos a explorar los tipos de retorno en un momento. Las funciones pueden tener el mismo nombre siempre que su tipo sea diferente, como se muestra en las dos definiciones de funciones anteriores.

El tipo de la primera función es (Cuerda) -> (), mientras que el tipo de la segunda función es(String, Int) -> (). El nombre de ambas funciones es el mismo. No te preocupes por el -> símbolo. Su significado se aclarará en unos momentos cuando discutamos los tipos de retorno..

El segundo PrintMessage (mensaje: veces :) función define dos parámetros, mensaje de tipo Cuerda y veces de tipo En t. Esta definición ilustra una de las características que Swift ha adoptado de Objective-C, funciones legibles y nombres de métodos. Mientras que el nombre de la función es imprimir mensaje, es fácil de entender qué se supone que debe hacer la función leyendo los nombres de los parámetros de la función.

En el segundo PrintMessage (mensaje: veces :) función, creamos un para-en bucle para imprimir el mensaje cuerda veces veces. Utilizamos el operador semiabierto., ... <, Como vimos anteriormente en esta serie.

Cuando empezamos a escribir imprimir mensaje en el patio de juegos, Xcode muestra ambas funciones en el menú de autocompletar. Gracias al tipo de función, es fácil elegir la función que nos interesa. Llamar al segundo PrintMessage (mensaje: veces :) La función es tan simple como:

printMessage (mensaje: "Hello World", veces: 3)

Valores predeterminados

Una de mis características favoritas es la capacidad de definir valores predeterminados para parámetros. Esto puede parecer una tontería si viene de un idioma que ha tenido esta característica durante años, pero es bastante bueno si ha estado trabajando con C y Objective-C durante muchos años..

En resumen, Swift permite a los desarrolladores definir valores predeterminados para los parámetros de una función. Definamos una nueva función que imprima la fecha actual en un formato específico. Asegúrese de agregar la siguiente declaración de importación en la parte superior de su área de juegos para importar el marco UIKit.

importar UIKit

Primero definamos el printDate (fecha: formato :) Funciona sin hacer uso de valores por defecto para ninguno de los parámetros..

func printDate (fecha: fecha, formato: cadena) dejar dateFormatter = DateFormatter () dateFormatter.dateFormat = format print (dateFormatter.string (from: date))

Si no está familiarizado con el marco de la Fundación y no entiende lo que está sucediendo en el cuerpo de la función, entonces está bien. El enfoque de este ejemplo no está en la implementación de formatear una fecha. En printDate (fecha: formato :), usamos el valor de la formato parámetro para formatear el valor de fecha. Si no pasamos un valor por el formato Parámetro, el compilador arroja un error..

Podemos remediar esto definiendo un valor predeterminado para el segundo parámetro de la función, como se muestra en la definición de función actualizada a continuación.

func printDate (fecha: fecha, formato: String = "YY / MM / dd") let dateFormatter = DateFormatter () dateFormatter.dateFormat = format print (dateFormatter.string (from: date))

Definir un valor predeterminado es tan simple como especificar un valor en la lista de parámetros en la definición de la función. El resultado es que el compilador ya no se queja y el error desaparece..

printDate (fecha: Fecha ())

Aunque hemos especificado un valor predeterminado para el formato parámetro, todavía podemos pasar un valor si queremos.

printDate (fecha: Fecha (), formato: "dd / MM / YY")

Tenga en cuenta que Apple recomienda colocar los parámetros con un valor predeterminado al final de la lista de parámetros. Esta es ciertamente una buena idea y es común en la mayoría de los otros lenguajes de programación que admiten parámetros opcionales.

3. Tipo de devolución

Las funciones que hemos visto hasta ahora no nos devuelven nada cuando las invocamos. Hagamos el printDate (fecha: formato :) La función es más útil devolviendo la fecha formateada como una cadena, en lugar de imprimir la fecha formateada en el cuerpo de la función. Esto requiere dos cambios, como se puede ver a continuación..

func printDate (fecha: Fecha, formato: String = "YY / MM / dd") -> String let dateFormatter = DateFormatter () dateFormatter.dateFormat = format return dateFormatter.string (from: date)

Lo primero que cambiamos es la definición de la función. Después de la lista de parámetros, especificamos el tipo de retorno., Cuerda. El tipo de retorno está precedido por el -> símbolo. Si has trabajado con CoffeeScript, esto te resultará familiar..

En lugar de imprimir la fecha formateada usando la imprimir (_: separador: terminador :) función, usamos el regreso palabra clave para devolver el valor de la función. Eso es todo lo que necesitamos hacer. Vamos a probarlo.

let formattedDate = printDate (date: Date (), format: "dd / MM / YY") print (formattedDate)

Invocamos el printDate (fecha: formato :) función, almacenar el valor devuelto en la constante formattedDate, e imprimir el valor de formattedDate En la salida estándar. Tenga en cuenta que el nombre de la printDate (fecha: formato :) La función ya no refleja lo que hace, por lo que es posible que desee cambiarla a formatDate en lugar.

Sin tipo de retorno

Las otras funciones que hemos definido en este tutorial no tienen un tipo de retorno. Cuando una función no tiene un tipo de retorno, no es necesario incluir el -> símbolo en la definición de la función.

Unos párrafos anteriores, les dije que ninguna de las funciones que habíamos definido nos devolvió un valor. Eso en realidad no es del todo cierto. Déjame explicarte los detalles esenciales con un experimento. Agregue la siguiente línea a su área de juegos y vea qué sucede.

Esto es interesante. Swift no tiene el problema de que almacenemos el valor de retorno de printHelloWorld () Funciona en una constante, pero nos advierte que el tipo de valor devuelto no es lo que podríamos pensar que es.

¿Que esta pasando aqui? Cada función en Swift devuelve un valor, incluso si no definimos un tipo de retorno en la definición de la función. Cuando una función no especifica explícitamente un tipo de retorno, la función devuelve implícitamente Vacío, que es equivalente a una tupla vacía, o () para abreviar. Puede ver esto en el panel de salida del patio y también se menciona en la advertencia de las salidas del compilador.

Podemos deshacernos de la advertencia anterior declarando explícitamente el tipo de valor, una tupla vacía. Estoy de acuerdo en que no es muy útil almacenar una tupla vacía en una constante, pero te muestra que cada función tiene un valor de retorno.

dejar valor: () = printHelloWorld ()

Tuplas

Otra gran característica de Swift es la capacidad de devolver múltiples valores de una función al devolver una tupla. El siguiente ejemplo ilustra cómo funciona esto. Déjame repetir que no es importante que entiendas cómo timeComponentsForDate (fecha :) La función hace su trabajo. El foco es el valor de retorno de la función, una tupla con tres elementos.

func timeComponentsForDate (_ date: Date) -> (hour: Int, minute: Int, second: Int) let dateComponents = Calendar.current.dateComponents ([. hour, .minute, .second], from: date) let hour = dateComponents.hour let minute = dateComponents.minute let second = dateComponents.second return (hora ?? 0, minuto ?? 0, segundo ?? 0)

La función acepta un argumento, un Fecha instancia, y devuelve una tupla con tres valores etiquetados. Etiquetar los valores de la tupla es solo por conveniencia; Es posible omitir las etiquetas..

func timeComponentsForDate (_ date: Date) -> (Int, Int, Int) let dateComponents = Calendar.current.dateComponents ([. hour, .minute, .second], from: date) let hour = dateComponents.hour let minute = dateComponents.minute let second = dateComponents.second return (hora ?? 0, minuto ?? 0, segundo ?? 0)

Sin embargo, como se ilustra en el siguiente ejemplo, etiquetar los valores de la tupla devuelta por la función es muy conveniente y hace que su código sea más fácil de entender.

let timeComponents = timeComponentsForDate (Date ()) print (timeComponents.hour) print (timeComponents.minute) print (timeComponents.second)

También es posible devolver un valor opcional de una función si hay escenarios en los que la función no tiene valor para devolver. Esto es tan simple como definir el tipo de retorno de la función como opcional, como se muestra a continuación.

func timeComponentsForDate (_ date: Date) -> (hour: Int, minute: Int, second: Int)? let dateComponents = Calendar.current.dateComponents ([. hour, .minute, .second], from: date) guard let hour = dateComponents.hour else return nil guard let minute = dateComponents.minute else return nil guard let second = dateComponents.second else return nil return (hora, minuto, segundo)

Conclusión

En este tutorial, exploramos los conceptos básicos de las funciones en Swift. Es importante que entiendas la sintaxis de las funciones, porque en el próximo artículo exploraremos funciones más avanzadas que se basan en lo que cubrimos en este tutorial..

Le animo a leer el artículo nuevamente si es necesario y, lo que es más importante, escriba algunas funciones en un área de juegos para familiarizarse con la sintaxis. Los conceptos básicos son fáciles de entender, pero solo los dominas practicando.

Si desea aprender a usar Swift 3 para codificar aplicaciones del mundo real, consulte nuestro curso Crear aplicaciones de iOS con Swift 3. Ya sea que sea nuevo en el desarrollo de aplicaciones de iOS o desee cambiar de Objective-C, este El curso te ayudará a comenzar con Swift para el desarrollo de aplicaciones..