NEW: Get your ticket for Hacking with Swift Live 2019! >>

< Previous: Switch case   Next: Opcionales (Optionals) >

Funciones

Las funciones te permiten definir piezas de código que cumplen con una tarea muy específica que puedes reutilizar. Usualmente las funciones pueden recibir algunos valores para modificar la forma en la que trabajan, sin embargo, no es obligatorio.

Empecemos con una función sencilla:

func favoriteAlbum() {
    print("My favorite is Fearless")
}

Si pones esta trozo de código en un playground verás que no se muestra nada. Y es correcto. La razón por la que no se muestra nada es que has puesto la sentencia que muestra el mensaje "My favorite is Fearless" en una función llamada favoriteAlbum() y esto no se va a ejecutar hasta que no le digamos a Swift que ejecute la función favoriteAlbum(). Para hacer esto, agrega la siguiente línea:

favoriteAlbum()

Esto ejecuta la función (o la "llama"), de modo que el mensaje "My favorite is Fearless" se muestra.

Como puedes observar, una función se declara escribiendo func seguido del nombre que se le quiere asignar a la función, seguido de paréntesis que abre y cierra (()). Ahora un bloque de código delimitado por llaves que abren y cierran ({}). Para llamar a la función se escribe el nombre de esta seguido de paréntesis que abre y cierra (()).

Seguramente este es un ejemplo demasiado sencillo - esa función hace lo mismo una y otra vez sin importar que, no teniendo motivo para haberse creado en primer lugar. Sin embargo, ¿qué haríamos si quisiéramos mostrar el nombre de un disco distinto cada vez que llamemos a la función? Bien, en ese caso, le diríamos a Swift que queremos que nuestra función acepte un valor cuando la llamemos y utilizar este valor dentro de la función.

Lo hacemos de esta manera:

func favoriteAlbum(name: String) {
    print("My favorite is \(name)")
}

Esto le dice a Swift que queremos que nuestra función acepte un valor (llamado "parámetro"), al que llamamos name, que debe ser una cadena (cadena de caracteres). Entonces, utilizamos la interpolación de cadenas para imprimir (o mostrar) el nombre de ese disco favorito. Para llamar a la función ahora escribiríamos esto:

favoriteAlbum(name: "Fearless")

Te estarás preguntando, qué sentido tiene, dado que es sólo una línea de código. Bien, imagina que utilizamos esta función en 20 sitios distintos en nuestra aplicación y el jefe de diseño pide que cambies el mensaje por "I love Fearless so much - it's my favorite!", ¿quieres realmente hacer este cambio en esos 20 sitios de tu código? Probablemente no. Usando una función solo tendrías que hacerlo una vez.

Puedes declarar tus funciones para que acepten tantos parámetros como quieras, hagamos que acepte nombre y año:

func printAlbumRelease(name: String, year: Int) {
    print("\(name) was released in \(year)")
}

printAlbumRelease(name: "Fearless", year: 2008)
printAlbumRelease(name: "Speak Now", year: 2010)
printAlbumRelease(name: "Red", year: 2012)

Los nombres de los parámetros de esta función son importantes y de hecho forman parte de la función misma. Algunas veces verás varias funciones con el mismo nombre, por ejemplo handle() pero con nombres de parámetros distintos para distinguir distintas acciones.

Parámetros internos y externos

En ocasiones queremos que nuestros parámetros tengan un nombre cuando llamamos a la función y otro dentro de la función. Esto quiere decir que cuando llamas a la función utilizas Inglés casi de forma natural, sin embargo, dentro de la función los parámetros tienen un nombre más acorde. Esta técnica es utilizada frecuentemente en Swift, por tanto es importante entenderla ahora mismo.

Para demostrar cómo funciona, escribamos una función que imprime el número de letras de una cadena de caracteres. Esto es posible utilizando la propiedad count del tipo de datos cadena de caracteres (String); podríamos escribirla así:

func countLettersInString(string: String) {
    print("The string \(string) has \(string.count) letters.")
}

Con esta función creada, podríamos llamarla de esta forma:

countLettersInString(string: "Hello")

Esto ciertamente funcionará, es un poco largo también. Además no es del tipo de cosas que dirías en voz alta: "count letters in string string hello".

La solución de Swift es permitirte especificar un nombre para el parámetro cuando llamamos a la función y otro dentro de ella. Para lograr esto, escribimos el nombre del parámetro dos veces seguidas - la primera para la llamada externa y la segunda para la interna.

Por ejemplo, podríamos llamar un parámetro myString cuando llamamos a la función y str dentro de la misma, así:

func countLettersInString(myString str: String) {
    print("The string \(str) has \(str.count) letters.")
}

countLettersInString(myString: "Hello")  

Podemos también utilizar guión bajo _ como nombre del parámetro externo, que indicará a Swift que, dicho parámetro, no tiene un nombre externo. Por ejemplo:

func countLettersInString(_ str: String) {
    print("The string \(str) has \(str.count) letters.")
}

countLettersInString("Hello")

Como puedes ver, esto hace que la línea de código se lea como una frase en Inglés: "count letters in string hello".

Mientras, ciertamente, hay muchos casos en los que utilizar _ es la elección correcta, los programadores de Swift prefieren darle nombre a todos los parámetros. Piensa en esto: ¿por qué necesitamos el nombre "String" en la función?, ¿en qué otra cosa podríamos querer contar letras?.

Entonces, lo que generalmente verás como nombres de parámetros externos será "in", "for" y "with", y nombres más significativos para los internos. De modo que, la forma "swifty" de escribir esta función es:

func countLetters(in string: String) {
    print("The string \(string) has \(string.count) letters.")
}

Esto significa que llamarás a la función con el nombre de parámetro "in", que no tendría sentido dentro de la función, sin embargo, "dentro" de esta el mismo parámetro se llama "string", que es mucho más significativo y útil. Entonces, llamaríamos a la función así:

countLetters(in: "Hello")

Y eso es la forma "swifty" de escribir código: "count letters in hello" se lee en Inglés de forma natural manteniendo un código claro.

Devolviendo valores

Las funciones en Swift pueden devolver un valor escribiendo -> y luego el tipo de dato, luego de la lista de parámetros. Una vez que haces esto, Swift se asegurará de que tu función devuelva un valor no importa qué, entonces, de nuevo, esto es una promesa de que tu código realmente devolverá un valor.

Como ejemplo, escribamos una función que devuelve "true" si el disco es de Taylor Swift o "false" si no lo es. Esta función acepta un parámetro (el nombre del disco a verificar) y devolverá un "Boolean". Podríamos crear la función así:

func albumIsTaylor(name: String) -> Bool {
    if name == "Taylor Swift" { return true }
    if name == "Fearless" { return true }
    if name == "Speak Now" { return true }
    if name == "Red" { return true }
    if name == "1989" { return true }

    return false
}

Si quieres puedes intentar incluyendo tu conocimiento, recién adquirido, sobre switch/case, esta función es un muy buen sitio para esto.

Puedes llamar a la función pasándole el nombre del disco y realizar alguna acción basada en su resultado, por ejemplo:

if albumIsTaylor(name: "Red") {
    print("That's one of hers!")
} else {
    print("Who made that?!")
}

if albumIsTaylor(name: "Blue") {
    print("That's one of hers!")
} else {
    print("Who made that?!")
}

HACKING WITH SWIFT LIVE This July is a new two-day event where you'll be inspired by great speakers on day one then learn all the amazing new features from WWDC on day two – click here for more information and tickets.

< Previous: Switch case   Next: Opcionales (Optionals) >
MASTER SWIFT NOW
Buy Testing Swift Buy Practical iOS 12 Buy Pro Swift Buy Swift Design Patterns Buy Swift Coding Challenges Buy Server-Side Swift (Vapor Edition) Buy Server-Side Swift (Kitura Edition) Buy Hacking with macOS Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with Swift Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Beyond Code

Was this page useful? Let me know!

Click here to visit the Hacking with Swift store >>