1. Antes de comenzar
En un codelab anterior, viste un programa simple que imprimió Hello, world!
. En los programas que escribiste hasta ahora, viste las siguientes dos funciones:
- Una función
main()
, que es obligatoria en todos los programas en Kotlin. Es el punto de entrada, o punto de partida, del programa. - Una función
println()
, a la que llamaste desdemain()
para generar texto.
En este codelab, aprenderás más sobre las funciones.
Las funciones te permiten dividir tu código en partes reutilizables, en lugar de incluir todo en main()
. Las funciones son un componente fundamental en las apps para Android, y aprender a definirlas y usarlas es un paso importante en tu recorrido para convertirte en desarrollador de Android.
Requisitos previos
- Conocimientos de los conceptos básicos de programación de Kotlin, incluidas las variables, y las funciones
println()
ymain()
Qué aprenderás
- Cómo definir y llamar a tus propias funciones.
- Cómo mostrar los valores de una función que puedes almacenar en una variable.
- Cómo definir y llamar a funciones con varios parámetros.
- Cómo llamar a funciones con argumentos con nombre.
- Cómo establecer valores predeterminados para los parámetros de la función.
Requisitos
- Un navegador web con acceso a Playground de Kotlin
2. Cómo definir una función y cómo llamarla
Antes de explorar las funciones en profundidad, revisemos la terminología básica.
- Declarar (o definir) una función usa la palabra clave
fun
e incluye código dentro de las llaves que contiene las instrucciones necesarias para ejecutar una tarea. - Llamar a una función causa que se ejecute todo el código dentro esta.
Hasta ahora, escribiste todo el código en la función main()
. En realidad, en ninguna parte del código se llama a la función main()
; el compilador de Kotlin la usa como punto de partida. La función main()
está diseñada para incluir solo otro código que desees ejecutar, como llamadas a la función println()
.
La función println()
es parte del lenguaje Kotlin. Sin embargo, puedes definir tus propias funciones. De esta manera, se permite reutilizar tu código si necesitas llamarlo más de una vez. Considera el siguiente programa como ejemplo.
fun main() {
println("Happy Birthday, Rover!")
println("You are now 5 years old!")
}
La función main()
consta de dos declaraciones println()
: una para desearle un feliz cumpleaños a Rover y otra que indica su edad.
Si bien Kotlin te permite colocar todo el código en la función main()
, es posible que no siempre desees hacerlo. Por ejemplo, si también quieres que tu programa contenga un saludo de Año Nuevo, la función main también deberá incluir esas llamadas a println()
. O bien, es posible que quieras saludar a Rover varias veces. Simplemente, puedes copiar y pegar el código o crear una función diferente para el saludo de cumpleaños. Harás lo último. Crear funciones diferentes para tareas específicas tiene una serie de beneficios.
- Código reutilizable: En lugar de copiar y pegar el código que necesitas usar más de una vez, simplemente puedes llamar a una función cuando sea necesario.
- Legibilidad: Garantizar que las funciones realicen una única tarea específica permite que otros desarrolladores y compañeros de equipo, así como tú mismo en el futuro, sepan con exactitud qué hace un fragmento de código.
La sintaxis para definir una función se muestra en el siguiente diagrama.
La definición de una función comienza con la palabra clave fun
, seguida del nombre de la función, un conjunto de paréntesis de apertura y cierre, y un conjunto de llaves de apertura y cierre. Entre llaves, se muestra el código que se ejecutará cuando se llame a la función.
Crearás una función nueva para quitar las dos declaraciones println()
de la función main()
.
- En tu navegador, abre el Playground de Kotlin y reemplaza el contenido con el siguiente código.
fun main() {
println("Happy Birthday, Rover!")
println("You are now 5 years old!")
}
- Después de la función
main()
, define una nueva función llamadabirthdayGreeting()
. Esta función se declara con la misma sintaxis que la funciónmain()
.
fun main() {
println("Happy Birthday, Rover!")
println("You are now 5 years old!")
}
fun birthdayGreeting() {
}
- Mueve las dos declaraciones
println()
demain()
a las llaves de la funciónbirthdayGreeting()
.
fun main() {
}
fun birthdayGreeting() {
println("Happy Birthday, Rover!")
println("You are now 5 years old!")
}
- En la función
main()
, llama a la funciónbirthdayGreeting()
. El código finalizado debería verse de la siguiente manera:
fun main() {
birthdayGreeting()
}
fun birthdayGreeting() {
println("Happy Birthday, Rover!")
println("You are now 5 years old!")
}
- Ejecuta tu código. Debería verse el siguiente resultado:
Happy Birthday, Rover! You are now 5 years old!
3. Cómo mostrar un valor de una función
En apps más complejas, las funciones no se limitan a imprimir texto.
Las funciones de Kotlin pueden generar datos que se denominan valor de muestra que se almacenan en una variable que puedes usar en cualquier otra parte del código.
Cuando defines una función, puedes especificar el tipo de datos del valor que deseas que se muestre. Para especificar el tipo de datos que se devuelve, debes colocar dos puntos (:
) después de los paréntesis, un solo espacio en blanco y, luego, el nombre del tipo (Int
, String
, etc.). A continuación, se coloca un solo espacio entre el tipo de datos que se devuelve y la llave de apertura. Dentro del cuerpo de la función, después de todas las sentencias, usa una sentencia return para especificar el valor que desea que muestre la función. Una sentencia return consiste en la palabra clave return
, seguida del valor, como una variable, que quieres que muestre la función como resultado.
La sintaxis para declarar una función con un tipo de datos que se devuelve es la siguiente.
El tipo Unit
De forma predeterminada, si no se especifica un tipo de datos que se muestra, el predeterminado es Unit
. Unit
significa que la función no muestra ningún valor. Unit
es equivalente a los tipos nulos de datos que se muestran en otros lenguajes (void
en Java y C, tupla Void
/vacía ()
en Swift; None
en Python, etc.). Cualquier función que no muestre un valor muestra Unit
de forma implícita. Si deseas observar este comportamiento, modifica tu código para que muestre Unit
.
- En la declaración de la función para
birthdayGreeting()
, agrega dos puntos después del paréntesis de cierre y especifica el tipo de datos que se muestra comoUnit
.
fun main() {
birthdayGreeting()
}
fun birthdayGreeting(): Unit {
println("Happy Birthday, Rover!")
println("You are now 5 years old!")
}
- Ejecuta el código y observa que todo continúa funcionando.
Happy Birthday, Rover! You are now 5 years old!
Es opcional especificar el tipo de datos que se muestra de Unit
en Kotlin. Para las funciones que no muestran nada o que muestran Unit
, no necesitas una sentencia return.
Cómo mostrar String
de birthdayGreeting()
A fin de demostrar cómo una función puede mostrar un valor, deberás modificar la función birthdayGreeting()
para que muestre una string, en lugar de simplemente imprimir el resultado.
- Reemplaza el tipo de datos que se muestra
Unit
porString
.
fun birthdayGreeting(): String {
println("Happy Birthday, Rover!")
println("You are now 5 years old!")
}
- Ejecuta tu código. Se mostrará un error. Si declaras un tipo de datos que se muestra para una función (p. ej.,
String
), esa función debe incluir una sentenciareturn
.
A 'return' expression required in a function with a block body ('{...}')
- Solo puedes mostrar una cadena de una función, no dos. Reemplaza las sentencias
println()
por dos variables,nameGreeting
yageGreeting,
con la palabra claveval
. Como quitaste las llamadas aprintln()
debirthdayGreeting()
, llamar abirthdayGreeting()
no imprimirá nada.
fun birthdayGreeting(): String {
val nameGreeting = "Happy Birthday, Rover!"
val ageGreeting = "You are now 5 years old!"
}
- Con la string que le da formato a la sintaxis que aprendiste en un codelab anterior, agrega una sentencia
return
para mostrar una string de la función que incluye ambos saludos.
Para dar formato a los saludos en una línea separada, también debes usar el carácter de escape \n
. Es similar al carácter de escape \"
que aprendiste en un codelab anterior. El carácter \n
se reemplaza por una línea nueva, de modo que los dos saludos estén en una línea separada.
fun birthdayGreeting(): String {
val nameGreeting = "Happy Birthday, Rover!"
val ageGreeting = "You are now 5 years old!"
return "$nameGreeting\n$ageGreeting"
}
- En
main()
, dado quebirthdayGreeting()
muestra un valor, puedes almacenar el resultado en una variable de string. Declara una variablegreeting
medianteval
para almacenar el resultado de la llamada abirthdayGreeting()
.
fun main() {
val greeting = birthdayGreeting()
}
- En
main()
, llama aprintln()
para imprimir la stringgreeting
. La funciónmain()
ahora debería verse de la siguiente manera:
fun main() {
val greeting = birthdayGreeting()
println(greeting)
}
- Ejecuta tu código y, luego, observa que el resultado sea el mismo que antes: Mostrar un valor te permite almacenar el resultado en una variable, pero ¿qué crees que sucede si llamas a la función
birthdayGreeting()
dentro de la funciónprintln()
?
Happy Birthday, Rover! You are now 5 years old!
- Quita la variable y, luego, pasa el resultado de la llamada a la función
birthdayGreeting()
a la funciónprintln()
:
fun main() {
println(birthdayGreeting())
}
- Ejecuta tu código y observa el resultado. El valor de muestra de la llamada a
birthdayGreeting()
se pasa directamente aprintln()
.
Happy Birthday, Rover! You are now 5 years old!
4. Cómo agregar un parámetro a la función birthdayGreeting()
Como viste, cuando llamas a la función println()
, puedes incluir una string entre paréntesis o pasar un valor a la función. Puedes hacer lo mismo con la función birthdayGreeting()
. Sin embargo, primero debes agregar un parámetro a birthdayGreeting()
.
Un parámetro especifica el nombre de una variable y un tipo de datos que puedes pasar a una función como datos para acceder dentro de esta. Los parámetros se declaran entre paréntesis después del nombre de la función.
Cada parámetro consiste en un nombre de variable y un tipo de datos, separados por dos puntos y un espacio. Si hay varios parámetros, se separan con una coma.
Por el momento, la función birthdayGreeting()
solo se puede usar para saludar a Rover. Agregarás un parámetro a la función birthdayGreeting()
para que puedas saludar con cualquier nombre que pases a la función.
- Dentro de los paréntesis de la función
birthdayGreeting()
, agrega un parámetroname
de tipoString
con la sintaxisname: String
.
fun birthdayGreeting(name: String): String {
val nameGreeting = "Happy Birthday, Rover!"
val ageGreeting = "You are now 5 years old!"
return "$nameGreeting\n$ageGreeting"
}
El parámetro definido en el paso anterior funciona como una variable declarada con la palabra clave val
. Su valor se puede usar en cualquier parte de la función birthdayGreeting()
. En un codelab anterior, aprendiste cómo insertar el valor de una variable en una string.
- Reemplaza
Rover
en la stringnameGreeting
por el símbolo$
seguido del parámetroname
.
fun birthdayGreeting(name: String): String {
val nameGreeting = "Happy Birthday, $name!"
val ageGreeting = "You are now 5 years old!"
return "$nameGreeting\n$ageGreeting"
}
- Ejecuta tu código y observa el error. Ahora que declaraste el parámetro
name
, debes pasar unString
cuando llames abirthdayGreeting()
. Cuando llamas a una función que toma un parámetro, debes pasar un argumento a la función. El argumento es el valor que pasas, como"Rover"
.
No value passed for parameter 'name'
- Pasa
"Rover"
a la llamadabirthdayGreeting()
enmain()
.
fun main() {
println(birthdayGreeting("Rover"))
}
- Ejecuta tu código y observa el resultado. El nombre Rover proviene del parámetro
name
.
Happy Birthday, Rover! You are now 5 years old!
- Como
birthdayGreeting()
toma un parámetro, puedes llamarlo con un nombre que no sea Rover. Agrega otra llamada abirthdayGreeting()
dentro de la llamada aprintln()
y pasa el argumento"Rex"
.
println(birthdayGreeting("Rover"))
println(birthdayGreeting("Rex"))
- Vuelve a ejecutar el código y, luego, observa que el resultado difiere en función del argumento que se pasó a
birthdayGreeting()
.
Happy Birthday, Rover! You are now 5 years old! Happy Birthday, Rex! You are now 5 years old!
5. Funciones con varios parámetros
Anteriormente, agregaste un parámetro para cambiar el saludo según el nombre. Sin embargo, también puedes definir más de un parámetro para una función, incluso parámetros de diferentes tipos de datos. En esta sección, modificarás el saludo de modo que también cambie en función de la edad del perro.
Las definiciones de los parámetros están separadas con comas. De manera similar, cuando llamas a una función con varios parámetros, también separas los argumentos que se pasaron con comas. Veamos esto en acción.
- Después del parámetro
name
, agrega un parámetroage
de tipoInt
a la funciónbirthdayGreeting()
. La declaración de la función nueva debe tener los dos parámetros,name
yage
, separados con comas:
fun birthdayGreeting(name: String, age: Int): String {
val nameGreeting = "Happy Birthday, $name!"
val ageGreeting = "You are now 5 years old!"
return "$nameGreeting\n$ageGreeting"
}
- La nueva string de saludo debe usar el parámetro
age
. Actualiza la funciónbirthdayGreeting()
para usar el valor del parámetroage
en la stringageGreeting
.
fun birthdayGreeting(name: String, age: Int): String {
val nameGreeting = "Happy Birthday, $name!"
val ageGreeting = "You are now $age years old!"
return "$nameGreeting\n$ageGreeting"
}
- Ejecuta la función y, luego, observa los errores en el resultado:
No value passed for parameter 'age' No value passed for parameter 'age'
- Modifica las dos llamadas a la función
birthdayGreeting()
enmain()
a fin de pasar una edad diferente para cada perro. Pasa5
para la edad de Rover y2
para la edad de Rex.
fun main() {
println(birthdayGreeting("Rover", 5))
println(birthdayGreeting("Rex", 2))
}
- Ejecuta tu código. Ahora que pasaste los valores para ambos parámetros, el resultado debería reflejar el nombre y la edad de cada perro cuando llames a la función.
Happy Birthday, Rover! You are now 5 years old! Happy Birthday, Rex! You are now 2 years old!
Firma de la función
Hasta ahora, viste cómo definir el nombre de la función, las entradas (parámetros) y los resultados. El nombre de la función y sus entradas (parámetros) se conocen colectivamente como firma de la función. La firma de la función consta de todo lo que está antes del tipo de datos que se muestra y se indica en el siguiente fragmento de código.
fun birthdayGreeting(name: String, age: Int)
A veces, los parámetros separados con comas se denominan lista de parámetros.
Con frecuencia, verás estos términos en la documentación para código que escriben otros desarrolladores. La firma de la función te indica el nombre de la función y los tipos de datos que se pueden pasar.
Ahora aprendiste un montón sobre la sintaxis nueva para definir funciones. Consulta el siguiente diagrama para obtener un resumen de la sintaxis de las funciones.
6. Argumentos con nombre
En los ejemplos anteriores, no tuviste que especificar los nombres de los parámetros, name
o age
, cuando llamaste a una función. Sin embargo, podrás hacerlo si así lo decides. Por ejemplo, puedes llamar a una función con muchos parámetros o pasar los argumentos en un orden diferente; por ejemplo, colocar el parámetro age
antes del parámetro name
. Cuando incluyes un nombre de parámetro si llamas a una función, esta se denomina argumento con nombre. Intenta usar un argumento con nombre con la función birthdayGreeting()
.
- Modifica la llamada para que Rex use argumentos con nombre como se muestra en este fragmento de código. Para ello, incluye el nombre del parámetro seguido de un signo igual y, luego, el valor (p. ej.,
name = "Rex"
).
println(birthdayGreeting(name = "Rex", age = 2))
- Ejecuta el código y, luego, observa que el resultado no haya cambiado:
Happy Birthday, Rover! You are now 5 years old! Happy Birthday, Rex! You are now 2 years old!
- Reordena los argumentos con nombres. Por ejemplo, coloca el argumento con nombre
age
antes del argumento con nombrename
.
println(birthdayGreeting(age = 2, name = "Rex"))
- Ejecuta el código y observa que el resultado sigue siendo el mismo. Si bien cambiaste el orden de los argumentos, se pasan los mismos valores para los mismos parámetros.
Happy Birthday, Rover! You are now 5 years old! Happy Birthday, Rex! You are now 2 years old!
7. Argumentos predeterminados
Los parámetros de la función también pueden especificar argumentos predeterminados. Quizás Rover es tu perro favorito, o esperas que se llame a una función con argumentos específicos en la mayoría de los casos. Cuando llamas a una función, puedes decidir omitir los argumentos para los que haya un valor predeterminado, en cuyo caso se usa el predeterminado.
Para agregar un argumento predeterminado, agrega un operador de asignación (=
) después del tipo de datos para el parámetro y configúralo del mismo modo que a un valor. Modifica tu código para usar un argumento predeterminado.
- En la función
birthdayGreeting()
, establece el parámetroname
en el valor predeterminado"Rover"
.
fun birthdayGreeting(name: String = "Rover", age: Int): String {
return "Happy Birthday, $name! You are now $age years old!"
}
- En la primera llamada a
birthdayGreeting()
para Rover enmain()
, establece el argumento con nombreage
en5
. Como el parámetroage
se define después dename
, debes usar el argumento con nombreage
. Sin los argumentos con nombre, Kotlin supone que el orden de los argumentos es el mismo en el que se definen los parámetros. El argumento con nombre se usa a fin de garantizar que Kotlin espere unInt
para el parámetroage
.
println(birthdayGreeting(age = 5))
println(birthdayGreeting("Rex", 2))
- Ejecuta tu código. La primera llamada a la función
birthdayGreeting()
muestra "Rover" como nombre porque nunca lo especificaste. La segunda llamada abirthdayGreeting()
todavía usa el valorRex
, que pasaste paraname
.
Happy Birthday, Rover! You are now 5 years old! Happy Birthday, Rex! You are now 2 years old!
- Quita el nombre de la segunda llamada a la función
birthdayGreeting()
. Una vez más, debido a que se omitename
, debes usar un argumento con nombre para la edad.
println(birthdayGreeting(age = 5))
println(birthdayGreeting(age = 2))
- Ejecuta tu código. Luego, observa que ambas llamadas a
birthdayGreeting()
imprimen "Rover" como nombre porque no se pasa ningún argumento con nombre.
Happy Birthday, Rover! You are now 5 years old! Happy Birthday, Rover! You are now 2 years old!
8. Conclusión
¡Felicitaciones! Aprendiste a definir funciones en Kotlin y a llamarlas.
Resumen
- Las funciones se definen con la palabra clave
fun
y contienen fragmentos de código reutilizables. - Las funciones facilitan el mantenimiento de los programas más grandes y evitan la repetición innecesaria de código.
- Las funciones pueden mostrar un valor que puedes almacenar en una variable para usarlo más tarde.
- Las funciones pueden tomar parámetros, que son variables disponibles dentro del cuerpo de una función.
- Los argumentos son los valores que pasas cuando llamas a una función.
- Puedes nombrar argumentos cuando llamas a una función. Cuando usas argumentos con nombre, puedes reordenarlos sin afectar el resultado.
- Puedes especificar un argumento predeterminado que te permita omitirlo cuando llames a una función.