Este codelab es parte del curso de capacitación de Kotlin para programadores. Aprovecharás al máximo este curso si trabajas con los codelabs de forma secuencial. Según tus conocimientos, es posible que puedas cambiar algunas secciones. Este curso está dirigido a programadores que conocen un lenguaje orientado a objetos y quieren aprender Kotlin.
Introducción
En este codelab, aprenderás los conceptos básicos del lenguaje de programación Kotlin: tipos de datos, operadores, variables, estructuras de control y variables que admiten valores nulos frente a variables que no los admiten. Este curso está dirigido a programadores que conocen un lenguaje orientado a objetos y quieren aprender Kotlin.
En lugar de crear una sola app de ejemplo, las lecciones de este curso están diseñadas para ampliar tus conocimientos, pero son semiindependientes entre sí para que puedas revisar las secciones con las que ya estás familiarizado. Para unirlos, muchos de los ejemplos usan un tema de acuario. Si quieres ver la historia completa del acuario, consulta el curso de Udacity Kotlin Bootcamp for Programmers.
Conocimientos que ya deberías tener
- Cómo crear un proyecto en IntelliJ IDEA
- Cómo abrir y ejecutar código en el REPL (bucle de lectura-evaluación-impresión) de Kotlin en IntelliJ IDEA (Tools > Kotlin > Kotlin REPL)
Qué aprenderás
- Cómo usar tipos de datos, operadores y variables de Kotlin
- Cómo trabajar con valores booleanos y condiciones
- La diferencia entre las variables que admiten valores nulos y las que no
- Cómo funcionan los arrays, las listas y los bucles en Kotlin
Actividades
- Trabaja con el REPL de Kotlin para aprender los conceptos básicos de Kotlin
En esta tarea, aprenderás sobre los operadores y los tipos en el lenguaje de programación Kotlin.
Paso 1: Explora los operadores numéricos
- Abre IntelliJ IDEA si aún no lo hiciste.
- Para abrir el REPL de Kotlin, selecciona Tools > Kotlin > Kotlin REPL.
Al igual que con otros lenguajes, Kotlin usa +
, -
, *
y /
para suma, resta, multiplicación y división. Kotlin también admite diferentes tipos de números, como Int
, Long
, Double
y Float
.
- Ingresa las siguientes expresiones en el REPL. Para ver el resultado, presiona
Control+Enter
(Command+Enter
en Mac) después de cada uno.
1+1 ⇒ res8: kotlin.Int = 2 53-3 ⇒ res9: kotlin.Int = 50 50/10 ⇒ res10: kotlin.Int = 5 1.0/2.0 ⇒ res11: kotlin.Double = 0.5 2.0*3.5 ⇒ res12: kotlin.Double = 7.0
Ten en cuenta que los resultados de las operaciones conservan los tipos de los operandos, por lo que 1/2 = 0, pero 1.0/2.0 = 0.5.
- Prueba algunas expresiones con diferentes combinaciones de números enteros y decimales.
6*50 ⇒ res13: kotlin.Int = 300 6.0*50.0 ⇒ res14: kotlin.Double = 300.0 6.0*50 ⇒ res15: kotlin.Double = 300.0
- Llama a algunos métodos en números. Kotlin mantiene los números como primitivos, pero te permite llamar a métodos en números como si fueran objetos.
2.times(3) ⇒ res5: kotlin.Int = 6 3.5.plus(4) ⇒ res8: kotlin.Double = 7.5 2.4.div(2) ⇒ res9: kotlin.Double = 1.2
Paso 2: Practica el uso de tipos
Kotlin no realiza conversiones implícitas entre tipos de números, por lo que no puedes asignar un valor corto directamente a una variable larga ni un Byte
a un Int
. Esto se debe a que la conversión implícita de números es una fuente común de errores en los programas. Siempre puedes asignar valores de diferentes tipos con la conversión.
- Para ver algunas de las conversiones posibles, define una variable de tipo
Int
en el REPL.
val i: Int = 6
- Crea una variable nueva y, luego, ingresa el nombre de la variable que se muestra arriba, seguido de
.to
.
val b1 = i.to
IntelliJ IDEA muestra una lista de posibles finalizaciones. Este autocompletado funciona para variables y objetos de cualquier tipo.
- Selecciona
toByte()
en la lista y, luego, imprime la variable.
val b1 = i.toByte()
println(b1)
⇒ 6
- Asigna un valor
Byte
a variables de diferentes tipos.
val b2: Byte = 1 // OK, literals are checked statically
println(b2)
⇒ 1
val i1: Int = b2
⇒ error: type mismatch: inferred type is Byte but Int was expected
val i2: String = b2
⇒ error: type mismatch: inferred type is Byte but String was expected
val i3: Double = b2
⇒ error: type mismatch: inferred type is Byte but Double was expected
- En el caso de las asignaciones que devolvieron errores, intenta transmitirlas.
val i4: Int = b2.toInt() // OK!
println(i4)
⇒ 1
val i5: String = b2.toString()
println(i5)
⇒ 1
val i6: Double = b2.toDouble()
println(i6)
⇒ 1.0
- Para que las constantes numéricas largas sean más legibles, Kotlin te permite colocar guiones bajos en los números donde te parezca conveniente. Intenta ingresar diferentes constantes numéricas.
val oneMillion = 1_000_000 val socialSecurityNumber = 999_99_9999L val hexBytes = 0xFF_EC_DE_5E val bytes = 0b11010010_01101001_10010100_10010010
Paso 3: Aprende el valor de los tipos de variables
Kotlin admite dos tipos de variables: modificables y no modificables. Con val
, puedes asignar un valor una vez. Si intentas asignar algo nuevamente, se mostrará un error. Con var
, puedes asignar un valor y, luego, cambiar el valor más adelante en el programa.
- Define variables con
val
yvar
, y, luego, asígnales valores nuevos.
var fish = 1
fish = 2
val aquarium = 1
aquarium = 2
⇒ error: val cannot be reassigned
Puedes asignar un valor a fish
y, luego, asignarle un valor nuevo, ya que se define con var
. Si intentas asignar un valor nuevo a aquarium
, se produce un error porque se define con val
.
El tipo que almacenas en una variable se infiere cuando el compilador puede deducirlo del contexto. Si lo deseas, siempre puedes especificar el tipo de una variable de forma explícita con la notación de dos puntos.
- Define algunas variables y especifica el tipo de forma explícita.
var fish: Int = 12
var lakes: Double = 2.5
Una vez que tú o el compilador asignan un tipo, no puedes cambiarlo, o bien recibirás un error.
Paso 4: Obtén información sobre las cadenas
Las cadenas en Kotlin funcionan de manera muy similar a las cadenas en cualquier otro lenguaje de programación, ya que usan "
para las cadenas y '
para los caracteres individuales, y puedes concatenar cadenas con el operador +
. Puedes crear plantillas de cadenas combinándolas con valores; el nombre $
variable
se reemplaza por el texto que representa el valor. Esto se denomina interpolación de variables.
- Crea una plantilla de cadena.
val numberOfFish = 5
val numberOfPlants = 12
"I have $numberOfFish fish" + " and $numberOfPlants plants"
⇒ res20: kotlin.String = I have 5 fish and 12 plants
- Crea una plantilla de cadena con una expresión. Al igual que en otros lenguajes, el valor puede ser el resultado de una expresión. Usa llaves
{}
para definir la expresión.
"I have ${numberOfFish + numberOfPlants} fish and plants"
⇒ res21: kotlin.String = I have 17 fish and plants
En esta tarea, aprenderás sobre los booleanos y la verificación de condiciones en el lenguaje de programación Kotlin. Al igual que otros lenguajes, Kotlin tiene booleanos y operadores booleanos, como menor que, igual a, mayor que, etcétera (<
, ==
, >
, !=
, <=
, >=
).
- Escribe una sentencia
if
/else
.
val numberOfFish = 50
val numberOfPlants = 23
if (numberOfFish > numberOfPlants) {
println("Good ratio!")
} else {
println("Unhealthy ratio")
}
⇒ Good ratio!
- Prueba con un rango en una sentencia
if
. En Kotlin, la condición que pruebas también puede usar rangos.
val fish = 50
if (fish in 1..100) {
println(fish)
}
⇒ 50
- Escribe un
if
con varios casos. Para condiciones más complicadas, usa el operador lógico Y&&
y el operador lógico O||
. Al igual que en otros lenguajes, puedes tener varios casos conelse if
.
if (numberOfFish == 0) {
println("Empty tank")
} else if (numberOfFish < 40) {
println("Got fish!")
} else {
println("That's a lot of fish!")
}
⇒ That's a lot of fish!
- Prueba una declaración
when
. Hay una mejor manera de escribir esa serie de sentenciasif
/else if
/else
en Kotlin, usando la sentenciawhen
, que es como la sentenciaswitch
en otros lenguajes. Las condiciones en una instrucciónwhen
también pueden usar rangos.
when (numberOfFish) {
0 -> println("Empty tank")
in 1..39 -> println("Got fish!")
else -> println("That's a lot of fish!")
}
⇒ That's a lot of fish!
En esta tarea, aprenderás sobre las variables anulables y no anulables. Los errores de programación que involucran valores nulos fueron la causa de innumerables errores. Kotlin busca reducir los errores con la introducción de variables no anulables.
Paso 1: Obtén información sobre la nulabilidad
De forma predeterminada, las variables no pueden ser null
.
- Declara un
Int
y asígnalenull
.
var rocks: Int = null
⇒ error: null can not be a value of a non-null type Int
- Usa el operador de signo de interrogación,
?
, después del tipo para indicar que una variable puede ser nula. Declara unInt?
y asígnalenull
.
var marbles: Int? = null
Cuando tienes tipos de datos complejos, como una lista, sucede lo siguiente:
- Puedes permitir que los elementos de la lista sean nulos.
- Puedes permitir que la lista sea nula, pero, si no lo es, sus elementos no pueden ser nulos.
- Puedes permitir que tanto la lista como los elementos sean nulos.
Las listas y otros tipos de datos complejos se explican en una tarea posterior.
Paso 2: Obtén más información sobre el signo de interrogación y operadores ?:
Puedes probar null
con el operador ?
, lo que te ahorra la molestia de escribir muchas instrucciones if
/else
.
- Escribe código de la forma más larga para verificar si la variable
fishFoodTreats
no esnull
. Luego, disminuye esa variable.
var fishFoodTreats = 6
if (fishFoodTreats != null) {
fishFoodTreats = fishFoodTreats.dec()
}
- Ahora, veamos la forma de escribirlo en Kotlin, usando el operador
?
.
var fishFoodTreats = 6
fishFoodTreats = fishFoodTreats?.dec()
- También puedes encadenar pruebas de nulos con el operador
?:
. Mira este ejemplo:
fishFoodTreats = fishFoodTreats?.dec() ?: 0
Es una abreviatura de "si fishFoodTreats
no es null
, disminúyelo y úsalo; de lo contrario, usa el valor después de ?:
, que es 0". Si fishFoodTreats
es null
, se detiene la evaluación y no se llama al método dec()
.
Un punto sobre los punteros nulos
Si realmente te gusta NullPointerExceptions
, Kotlin te permite conservarlos. El operador de aserción no nula, !!
(doble signo de exclamación), convierte cualquier valor en un tipo no nulo y arroja una excepción si el valor es null
.
val len = s!!.length // throws NullPointerException if s is null
En esta tarea, aprenderás sobre arrays y listas, y conocerás diferentes formas de crear bucles en el lenguaje de programación Kotlin.
Paso 1: Haz listas
Las listas son un tipo fundamental en Kotlin y son similares a las listas de otros lenguajes.
- Declara una lista con
listOf
y, luego, imprímela. No se puede cambiar esta lista.
val school = listOf("mackerel", "trout", "halibut")
println(school)
⇒ [mackerel, trout, halibut]
- Declara una lista que se puede cambiar con
mutableListOf
. Quita un elemento.
val myList = mutableListOf("tuna", "salmon", "shark")
myList.remove("shark")
⇒ res36: kotlin.Boolean = true
El método remove()
devuelve true
cuando quita correctamente el elemento que se pasó.
Paso 2: Crea arrays
Al igual que otros lenguajes, Kotlin tiene arrays. A diferencia de las listas en Kotlin, que tienen versiones mutables e inmutables, no hay una versión mutable de un Array
. Una vez que creas un array, su tamaño es fijo. No puedes agregar ni quitar elementos, excepto si los copias en un array nuevo.
Las reglas sobre el uso de val
y var
son las mismas con los arrays que con las listas.
- Declara un array de cadenas con
arrayOf
. Usa la utilidad de matrizjava.util.Arrays.toString()
para imprimirla.
val school = arrayOf("shark", "salmon", "minnow")
println(java.util.Arrays.toString(school))
⇒ [shark, salmon, minnow]
- Un array declarado con
arrayOf
no tiene un tipo asociado a los elementos, por lo que puedes mezclar tipos, lo que resulta útil. Declara un array con diferentes tipos.
val mix = arrayOf("fish", 2)
- También puedes declarar arrays con un solo tipo para todos los elementos. Declara un array de números enteros con
intArrayOf()
. Existen compiladores o funciones de instanciación correspondientes para arrays de otros tipos.
val numbers = intArrayOf(1,2,3)
- Combina dos arrays con el operador
+
.
val numbers = intArrayOf(1,2,3)
val numbers3 = intArrayOf(4,5,6)
val foo2 = numbers3 + numbers
println(foo2[5])
=> 3
- Prueba diferentes combinaciones de arrays y listas anidados. Al igual que en otros lenguajes, puedes anidar arrays y listas. Es decir, cuando colocas un array dentro de otro, tienes un array de arrays, no un array aplanado del contenido de los dos. Los elementos de un array también pueden ser listas, y los elementos de las listas pueden ser arrays.
val numbers = intArrayOf(1, 2, 3)
val oceans = listOf("Atlantic", "Pacific")
val oddList = listOf(numbers, oceans, "salmon")
println(oddList)
⇒ [[I@89178b4, [Atlantic, Pacific], salmon]
El primer elemento, numbers
, es un Array
. Cuando no usas la utilidad de array para imprimirlo, Kotlin imprime la dirección en lugar del contenido del array.
- Una característica interesante de Kotlin es que puedes inicializar arrays con código en lugar de inicializarlos en 0. Prueba con este ejemplo:
val array = Array (5) { it * 2 }
println(java.util.Arrays.toString(array))
⇒ [0, 2, 4, 6, 8]
El código de inicialización se encuentra entre las llaves, {}
. En el código, it
hace referencia al índice del array, que comienza con 0.
Paso 3: Crea bucles
Ahora que tienes listas y arrays, iterar los elementos funciona como esperas.
- Crea un array. Usa un bucle
for
para iterar a través del array y, luego, imprimir los elementos.
val school = arrayOf("shark", "salmon", "minnow")
for (element in school) {
print(element + " ")
}
⇒ shark salmon minnow
- En Kotlin, puedes iterar los elementos y los índices al mismo tiempo. Prueba con este ejemplo:
for ((index, element) in school.withIndex()) {
println("Item at $index is $element\n")
}
⇒ Item at 0 is shark Item at 1 is salmon Item at 2 is minnow
- Prueba diferentes tamaños y rangos de pasos. Puedes especificar rangos de números o de caracteres, en orden alfabético. Y, al igual que en otros idiomas, no tienes que avanzar de a 1. Puedes retroceder con
downTo
.
for (i in 1..5) print(i)
⇒ 12345
for (i in 5 downTo 1) print(i)
⇒ 54321
for (i in 3..6 step 2) print(i)
⇒ 35
for (i in 'd'..'g') print (i)
⇒ defg
- Prueba algunos bucles. Al igual que otros lenguajes, Kotlin tiene bucles
while
, buclesdo...while
y operadores++
y--
. Kotlin también tiene buclesrepeat
.
var bubbles = 0
while (bubbles < 50) {
bubbles++
}
println("$bubbles bubbles in the water\n")
do {
bubbles--
} while (bubbles > 50)
println("$bubbles bubbles in the water\n")
repeat(2) {
println("A fish is swimming")
}
⇒ 50 bubbles in the water 49 bubbles in the water A fish is swimmingA fish is swimming
Kotlin es muy similar a otros lenguajes cuando se trata de conceptos básicos, como operadores, listas y bucles, pero existen algunas diferencias importantes.
Las siguientes funciones pueden ser diferentes en Kotlin de lo que estás acostumbrado a ver en otros lenguajes:
- Los tipos de Kotlin no se pueden convertir de forma implícita. Usa la conversión de tipos.
- Las variables declaradas con
val
solo se pueden asignar una vez. - De forma predeterminada, las variables de Kotlin no admiten valores nulos. Usa
?
para hacer que las variables sean anulables. - Con Kotlin, puedes recorrer el índice y los elementos de un array al mismo tiempo en un bucle
for
.
Las siguientes construcciones de programación de Kotlin son similares a las de otros lenguajes:
- Los arrays y las listas pueden tener un solo tipo o tipos mixtos.
- Los arrays y las listas se pueden anidar.
- Puedes crear bucles con
for
,while
,do
/while
yrepeat
. - La sentencia
when
es la versión de Kotlin de la sentenciaswitch
, perowhen
es más flexible.
Documentación de Kotlin
Si deseas obtener más información sobre algún tema de este curso o si te quedas atascado, https://kotlinlang.org es el mejor punto de partida.
- Conversión de tipos explícita
- Definición de variables
- Plantillas de strings
- Valores anulables
- Listas
- Arrays
if
,when
,for
,while
- Operador
?:
(Elvis) - Operador
!!
Instructivos de Kotlin
El sitio web https://try.kotlinlang.org incluye instructivos enriquecidos llamados Kotlin Koans, un intérprete basado en la Web y un conjunto completo de documentación de referencia con ejemplos.
Curso de Udacity
Para ver el curso de Udacity sobre este tema, consulta Capacitación de Kotlin para programadores.
IntelliJ IDEA
Encontrarás la documentación de IntelliJ IDEA en el sitio web de JetBrains.
En esta sección, se enumeran las posibles actividades para el hogar para los alumnos que trabajan en este codelab como parte de un curso dirigido por un instructor. Depende del instructor hacer lo siguiente:
- Si es necesario, asigna una tarea.
- Comunicarles a los alumnos cómo enviar las actividades para el hogar.
- Califica las actividades para el hogar.
Los instructores pueden usar estas sugerencias en la medida que quieran y deben asignar cualquier otra actividad para el hogar que consideren apropiada.
Si estás trabajando en este codelab por tu cuenta, usa estas actividades para el hogar para probar tus conocimientos.
Responde estas preguntas:
Pregunta 1
¿Cuál de las siguientes opciones declara una lista inmutable de cadenas?
▢ val school = arrayOf("shark", "salmon", "minnow")
▢ var school = arrayOf("shark", "salmon", "minnow")
▢ val school = listOf("shark", "salmon", "minnow")
▢ val school = mutableListOf("shark", "salmon", "minnow")
Pregunta 2
¿Cuál será el resultado del siguiente código?for (i in 3..8 step 2) print(i)
▢ 345678
▢ 468
▢ 38
▢ 357
Pregunta 3
¿Cuál es el propósito del signo de interrogación en este código?var rocks: Int? = 3
▢ El tipo de la variable rocks
no está fijo.
▢ La variable rocks
se puede establecer como nula.
▢ La variable rocks
no se puede establecer como nula.
▢ La variable rocks
no se debe inicializar de inmediato.
Continúa con la siguiente lección:
Para obtener una descripción general del curso, incluidos los vínculos a otros codelabs, consulta "Capacitación de Kotlin para programadores: Bienvenido al curso".