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.
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.
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?!")
}
SAVE 50% All our books and bundles are half price for Black Friday, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.
Link copied to your pasteboard.