Recordad que la forma más sencilla de comprobar todos estos códigos es en la web de Kotlin PlayGround.
Paquetes
Como pasa en Java, en Kotlin los paquetes se colocan en la parte superior del archivo:
package com.example import com.example.* // ...
Variables
Hay dos tipos de variables, val
y var
.
La variable val
una vez asignada solo se puede leer, es decir, una vez se le asigna su valor no puede cambiar. val
en Kotlin sería como añadir a final
a una variable en Java.
var
por otro lado si podría cambiar su valor.
fun main() { //sampleStart val numeroFinal = 2 // Deduce que el tipo es 'Int' numeroFinal = 3 // Provocaría un error ya que no se puede volver a asignar var numeroVariable = 2 // Deduce que el tipo es 'Int' numeroVariable = 4 // No generaría un error numeroVariable = "hola" // Provocaría un error ya que es de tipo 'Int' val numeroTardio: Int // Puedes asignar el valor más tarde numeroTardio = 6 //sampleEnd }
Como has visto en el bloque de código anterior, no es necesario indicarle el tipo, ya que Kotlin puede detectarlo automáticamente una vez que le asignas un valor.
También es posible indicar el tipo si así lo deseas:
val numero: Int = 1 // Le indicas explícitamente que es de tipo 'Int'
Funciones
Las funciones en Kotlin se definen con fun
, por ejemplo vamos a hacer una función que sume dos números y los muestre por pantalla:
//sampleStart fun mostrarSuma(a: Int, b: Int) { println("La suma de $a y $b es ${a + b}") } //sampleEnd fun main() { mostrarSuma(1, 4) }
Con la siguiente función vamos a ver como devolver un valor, en este caso un entero, añadiendo el tipo al final, en este caso Int
:
//sampleStart fun suma(a: Int, b: Int): Int { return a + b } //sampleEnd fun main() { println("La suma sería de 1 y 4 es ${suma(1, 4)}") }
Otra forma de definir esa función es la siguiente:
//sampleStart fun suma(a: Int, b: Int) = a + b // Deduce el tipo 'Int' //sampleEnd fun main() { println("La suma sería de 1 y 4 es ${suma(1, 4)}") }
Esta forma es muy útil con funciones simples ya que facilita su lectura y puedes ahorrar un montón del líneas.
Plantillas de Texto
Te habrás fijado que en una de las funciones anteriores ya hemos una plantilla, y que gracias a ellas con Kotlin no vamos a tener que utilizar el signo +
para encadenar textos que tanto se ha usado en Java.
Su uso es muy simple, solo tienes que usar el símbolo $
y el nombre de la variable:
fun main() { //sampleStart var numero = 1 val texto = "El número es $numero" println(texto) // "El número es 1" //sampleEnd }
Sentencias Condicionales
No tiene demasiado misterio ya que en Kotlin su sintaxis es prácticamente idéntica a Java:
//sampleStart fun mayorNumero(a: Int, b: Int): Int { if (a > b) { return a } else { return b } } //sampleEnd fun main() { println("El mayor número de 2 y 3 es ${mayorNumero(2, 3)}") }
Una forma de ahorrar código sería:
//sampleStart fun mayorNumero(a: Int, b: Int) = if (a > b) a else b //sampleEnd fun main() { println("El mayor número de 2 y 3 es ${mayorNumero(2, 3)}") }
Bucles
La sintaxis de Kotlin para los bucles difiere de la de Java un poco.
For
Los intervalos de Kotlin serían los clásicos bucles for
con i
en Java.
fun main() { //sampleStart for (i in 1..3) { print("$i ") // "1 2 3" } //sampleEnd }
fun main() { //sampleStart for (i in 10 downTo 0 step 2) { print("$i ") // "10 8 6 4 2 0" } //sampleEnd }
Mientras tanto, con los bucles for
en Kotlin nos estaríamos refiriendo a los foreach
de Java.
fun main() { //sampleStart val frutas = listOf("platano", "manzana", "pera", "kiwi") for (fruta in frutas) { println(fruta) } //sampleEnd }
Si quisiésemos utilizar una plantilla de texto con un índice:
fun main() { //sampleStart val frutas = listOf("platano", "manzana", "pera", "kiwi") for (index in frutas.indices) { println("La fruta en la posición $index es ${frutas[index]}") } //sampleEnd }
When
Esta expresión en Kotlin sería el equivalente a Switch en Java:
//sampleStart fun describir(obj: Any): String = when (obj) { 1 -> "Uno" "hola" -> "Saludos" is Int -> "Número entero" !is String -> "No es un texto" else -> "Desconocido" } //sampleEnd fun main() { println(describir(1)) // "Uno" println(describir("hola")) // "Saludos" println(describir(3)) // "Número entero" println(describir(true)) // "No es un texto" }
Con Any
lo que le estamos indicando es que objeto puede ser de cualquier tipo.
While
import kotlin.random.Random fun main() { //sampleStart var numero = 0 while (numero!=2) { numero = Random.nextInt(0,6) print("$numero ") } //sampleEnd }
Colecciones
Iterar a través de una colección:
fun main() { //sampleStart val frutas = listOf("platano", "manzana", "pera", "kiwi") for (fruta in frutas) { println(fruta) } //sampleEnd }
Para comprobar si una colección contiene un objeto:
fun main() { val frutas = listOf("platano", "manzana", "pera", "kiwi") for (fruta in frutas) { println(fruta) } //sampleStart when { "naranja" in frutas -> println("zumo") "manzana" in frutas -> println("me gusta la manzana") } //sampleEnd }
Utilizando expresiones lambda para filtrar y mapear una colección
fun main() { val frutas = listOf("platano", "manzana", "pera", "kiwi") //sampleStart frutas.filter { it.startsWith("p") } .sortedBy { it } .map { it.toUpperCase() } .forEach { println(it) } //sampleEnd }
Crear clases básicas y sus instancias
En el siguiente ejemplo vas a ver como Kotlin nos ahorra un montón de código respecto a Java, sobretodo al crear la clase, ya que no necesitamos indicarle los getters and setters, ni colocar todos los valores en el constructor con la palabra this
.
//sampleStart class Rectangulo(val ancho: Int, val largo: Int) { fun mostrar() = print("La base es de $ancho cm y la altura es de $largo cm") } //sampleEnd fun main() { val rectangulo = Rectangulo(5, 2) // Instanciamos 'Rectangulo' val ancho = rectangulo.ancho // Acceso a la propiedad 'ancho' val largo = rectangulo.largo // Acceso a la propiedad 'largo' val area = largo * ancho println("El area es $area cm") // "El area es 10 cm" rectangulo.mostrar() // Se ejecuta la función 'mostrar' }
Valores nulos y su control
Si por algún motivo quieres que algo sea nulo, en Kotlin puedes indicarlo mediante el símbolo ?
.
Por ejemplo, si la siguiente función le pasásemos un texto que no sea número entero, devolvería null
.
fun main() { //sampleStart val numeroString = "10" // Tipo string val numeroInt = numeroString.toIntOrNull() // Si es un número entero será Int, sino será null println(numeroInt ?: "No es un número") // "10" val texto = "Hola" val numero = texto.toIntOrNull() // Será 'null' en este caso println(numero ?: "No es un número") // "No es un número" //sampleEnd }
Controles de tipos y conversiones automáticas
El operador is
es el encargado de comprobar si una expresión es un tipo o una instancia. Si una variable local es inmutable o se le ha indicado el tipo específicamente, no hay necesidad de hacer una conversión (casting) explícita.
//sampleStart fun obtenerTipo(valor: Any): String { return when (valor) { is String -> "String" is Int -> "Int" is Boolean -> "Boolean" else -> "Tipo desconocido" } } //sampleEnd fun main() { println(obtenerTipo("Hola")) // "String" println(obtenerTipo(10)) // "Int" println(obtenerTipo(true)) // "Boolean" println(obtenerTipo(20f)) // "Tipo Desconocido" ya que no hemos definido float }