Kotlin Cheat Sheet
Última actualización
Hello World y conceptos básicos
Un programa Kotlin empieza en una función main de nivel superior: no hace falta una clase.
| Sintaxis | Significado |
|---|---|
fun main() { println("Hello") } | Punto de entrada de un programa |
println("text") | Imprimir una línea en la salida estándar |
print("text") | Imprimir sin salto de línea al final |
// comment | Comentario de una línea |
/* comment */ | Comentario de varias líneas |
val input = readLine() | Leer una línea de stdin (String? nullable) |
val line = readln() | Leer una línea de stdin (no nulo, Kotlin 1.6+) |
Variables (val / var) y tipos
Prefiere val; usa var solo cuando el valor tenga que cambiar.
| Sintaxis | Significado |
|---|---|
val name = "Ada" | Variable de solo lectura, tipo inferido como String |
var count = 0 | Variable mutable |
val age: Int = 30 | Anotación de tipo explícita |
Int, Long, Double, Float | Tipos numéricos (42, 42L, 3.14, 3.14f) |
Boolean, Char, String | true/false, 'a', "texto" |
val big = 1_000_000 | Guiones bajos para literales legibles |
"3".toInt(), "2.5".toDouble() | Convertir un string en número |
42.toString() | Número a string |
const val MAX = 10 | Constante en tiempo de compilación (nivel superior o en un object) |
Strings y plantillas
Las plantillas de string sustituyen a la concatenación casi siempre.
| Sintaxis | Significado |
|---|---|
"Hi, $name" | Insertar una variable en un string |
"Total: ${price * qty}" | Insertar una expresión |
s.length | Número de caracteres |
s.uppercase(), s.lowercase() | Cambiar mayúsculas/minúsculas |
s.trim() | Quitar espacios al principio y al final |
s.contains("x"), s.startsWith("a") | Buscar dentro de un string |
s.substring(0, 3) | Cortar por rango de índices |
s.split(",") | Dividir en una List<String> |
s[0] | Carácter en un índice |
"""raw text""" | String crudo de varias líneas, sin escapes |
"%.2f".format(3.14159) | Salida formateada (3.14) |
Null safety
Un tipo no admite nulos por defecto; añade ? para permitir null y el compilador te obliga a tratarlo.
| Sintaxis | Significado |
|---|---|
var s: String? = null | Tipo nullable |
s?.length | Llamada segura: devuelve null si s es null |
s?.length ?: 0 | Operador Elvis: valor por defecto cuando es null |
s!!.length | Aserción de no nulo: lanza excepción si s es null |
if (s != null) s.length | Smart cast a no nulo dentro de la comprobación |
s?.let { println(it) } | Ejecutar un bloque solo cuando no es null |
val n = s?.toIntOrNull() | Convertir, o null si la entrada no es válida |
lateinit var x: String | Variable no nula inicializada más tarde |
Operadores
| Operador | Significado |
|---|---|
+ - * / % | Aritmética (/ entre Int es división entera) |
+= -= *= /= %= | Asignación compuesta |
++ -- | Incremento / decremento |
== != | Igualdad estructural (llama a equals) |
=== !== | Igualdad referencial (mismo objeto) |
< > <= >= | Comparación |
&& || ! | Y / o / no lógicos |
a in 1..10 | Pertenencia a un rango o colección |
x as Int, x as? Int | Cast / cast seguro (null si falla) |
x is String | Comprobación de tipo (smart cast si acierta) |
Control de flujo (if / when)
if y when son expresiones: devuelven un valor.
| Sintaxis | Significado |
|---|---|
if (a > b) x else y | if como expresión (Kotlin no tiene ternario ?:) |
if (c) { ... } else if (d) { ... } else { ... } | Ramas encadenadas |
when (x) { 1 -> "one"; 2 -> "two"; else -> "other" } | Comparar con un valor |
when (x) { 1, 2 -> "low" } | Varios valores en una rama |
when (x) { in 1..9 -> "digit" } | Comparar con un rango |
when (x) { is String -> x.length } | Comparar con un tipo (con smart cast) |
when { x < 0 -> "neg"; x == 0 -> "zero"; else -> "pos" } | when sin sujeto, como if/else if |
val label = when (x) { ... } | when como expresión (necesita else) |
Bucles y rangos
| Sintaxis | Significado |
|---|---|
for (i in 1..5) | Rango inclusivo de 1 a 5 |
for (i in 1 until 5) | De 1 a 4 (fin exclusivo) |
for (i in 0..<5) | Lo mismo con la sintaxis de rango abierto (Kotlin 1.9+) |
for (i in 10 downTo 1 step 2) | Contar hacia atrás por pasos |
for (item in list) | Recorrer una colección |
for ((i, item) in list.withIndex()) | Índice y elemento a la vez |
for (ch in "abc") | Recorrer los caracteres de un string |
while (cond) { ... } | Repetir mientras sea verdadero |
do { ... } while (cond) | Ejecutar al menos una vez |
break, continue | Salir del bucle / saltar a la siguiente iteración |
repeat(3) { println(it) } | Ejecutar un bloque n veces |
Funciones
| Sintaxis | Significado |
|---|---|
fun add(a: Int, b: Int): Int { return a + b } | Declarar una función |
fun add(a: Int, b: Int) = a + b | Función de una sola expresión, tipo de retorno inferido |
fun greet(name: String = "world") | Valor por defecto de un parámetro |
greet(name = "Ada") | Argumento con nombre |
fun log(vararg items: String) | Número variable de argumentos |
fun say(): Unit | Sin valor de retorno (Unit es opcional) |
val square = { x: Int -> x * x } | Lambda guardada en una variable |
fun String.shout() = uppercase() + "!" | Función de extensión |
fun apply(f: (Int) -> Int) = f(2) | Función como parámetro |
list.map { it * 2 } | Lambda final, it es el único parámetro |
Listas
listOf es de solo lectura; mutableListOf se puede modificar.
| Sintaxis | Significado |
|---|---|
val nums = listOf(1, 2, 3) | Lista de solo lectura |
val items = mutableListOf("a") | Lista mutable |
nums[0], nums.first(), nums.last() | Acceder a elementos |
nums.getOrNull(9) | Acceso seguro, null si está fuera de rango |
items.add("b"), items.remove("a") | Añadir / eliminar |
items[0] = "z" | Reemplazar por índice |
nums.size, nums.isEmpty() | Tamaño y si está vacía |
x in nums, nums.contains(x) | Pertenencia |
nums.indexOf(2) | Posición de un elemento, -1 si no está |
nums.subList(0, 2) | Sublista (fin exclusivo) |
nums.take(2), nums.drop(1) | Los primeros n / todos menos los primeros n |
nums.sorted(), nums.reversed() | Nueva lista ordenada / invertida |
nums.sum(), nums.average(), nums.maxOrNull() | Agregados |
nums.joinToString(", ") | Unir en un solo string |
Pair(1, "a"), 1 to "a", Triple(1, 2, 3) | Tuplas pequeñas de tamaño fijo |
Mapas y sets
| Sintaxis | Significado |
|---|---|
val m = mapOf("a" to 1, "b" to 2) | Mapa de solo lectura |
val mm = mutableMapOf<String, Int>() | Mapa mutable |
m["a"] | Búsqueda (null si no existe) |
m.getOrDefault("z", 0) | Búsqueda con valor por defecto |
mm["c"] = 3 | Insertar o actualizar |
for ((k, v) in m) | Recorrer entradas con desestructuración |
m.keys, m.values | Colecciones de claves / valores |
"a" in m | Pertenencia de una clave |
val s = setOf(1, 2, 2) | Set de valores únicos ({1, 2}) |
mutableSetOf<Int>() | Set mutable |
Operaciones sobre colecciones (lambdas)
| Sintaxis | Significado |
|---|---|
list.map { it * 2 } | Transformar cada elemento |
list.filter { it > 2 } | Conservar los elementos que cumplen la condición |
list.forEach { println(it) } | Hacer algo con cada elemento |
list.any { it > 2 }, list.all { it > 0 } | ¿Algún / todo elemento cumple la condición? |
list.count { it % 2 == 0 } | Contar coincidencias |
list.find { it > 2 } | Primera coincidencia o null |
list.sortedBy { it.length } | Ordenar por una clave |
list.groupBy { it.first() } | Agrupar en un Map |
list.distinct() | Eliminar duplicados |
list.fold(0) { acc, x -> acc + x } | Reducir con un valor inicial |
list.zip(other) | Emparejar dos listas |
list.flatMap { it.toList() } | Transformar y luego aplanar |
Clases y data classes
| Sintaxis | Significado |
|---|---|
class User(val name: String, var age: Int) | Clase con constructor primario y propiedades |
val u = User("Ada", 36) | Crear una instancia (sin new) |
u.name, u.age = 37 | Leer / escribir propiedades |
data class Point(val x: Int, val y: Int) | equals, hashCode, toString, copy gratis |
p.copy(y = 5) | Copia con algunas propiedades cambiadas |
val (x, y) = p | Declaración de desestructuración |
open class Base, class Sub : Base() | Herencia (las clases son final por defecto) |
override fun toString() = "..." | Sobrescribir un miembro |
object Config { val debug = true } | Singleton |
companion object { fun create() = User("", 0) } | Miembros de tipo estático |
enum class Color { RED, GREEN } | Enum |
sealed class Result | Jerarquía de clases restringida, exhaustiva en when |
interface Shape { fun area(): Double } | Interfaz |
Manejo de errores
| Sintaxis | Significado |
|---|---|
try { ... } catch (e: Exception) { ... } | Capturar una excepción |
try { ... } finally { ... } | Ejecutar siempre la limpieza |
val n = try { s.toInt() } catch (e: NumberFormatException) { 0 } | try como expresión |
throw IllegalArgumentException("bad") | Lanzar una excepción |
require(x > 0) { "x must be positive" } | Comprobación de argumento (lanza IllegalArgumentException) |
check(ready) { "not ready" } | Comprobación de estado (lanza IllegalStateException) |
s.toIntOrNull() | Devolver null en lugar de lanzar |
runCatching { risky() }.getOrDefault(0) | Envolver una llamada en un Result |
Funciones de ámbito
Cinco pequeñas ayudas para trabajar con un objeto dentro de un bloque.
| Sintaxis | Significado |
|---|---|
x.let { it + 1 } | it es el objeto, devuelve el resultado del bloque |
x.run { this + 1 } | this es el objeto, devuelve el resultado del bloque |
x.apply { field = 1 } | this es el objeto, devuelve el objeto |
x.also { println(it) } | it es el objeto, devuelve el objeto |
with(x) { field } | No es una extensión; this es x, devuelve el resultado del bloque |
x?.let { ... } | La comprobación de nulo idiomática + uso |
Toda la sintaxis de Kotlin que buscas, en una sola página. Este cheat sheet de Kotlin es una referencia rápida del lenguaje detrás de Android y de buena parte de la JVM moderna: declarar variables, manejar nulos con seguridad, ramificar con when, recorrer rangos, escribir funciones y trabajar con listas y mapas.
Todo lo que hay aquí es Kotlin estándar y funciona igual en la JVM, en Android y con Kotlin Multiplatform. Copia lo que necesites o pruébalo en vivo en el playground de Kotlin: pega un fragmento, pulsa Run y mira la salida en tu navegador.
Preguntas frecuentes sobre el cheat sheet de Kotlin
¿Este cheat sheet de Kotlin es gratis?
when, un operador de null safety o un método de colección.¿Cuál es la diferencia entre val y var en Kotlin?
val declara una referencia de solo lectura: se asigna una vez y no puede reasignarse. var declara una variable mutable que sí puede reasignarse. Ten en cuenta que val solo fija la referencia: a una val list = mutableListOf(1) todavía se le pueden añadir elementos. El estilo Kotlin es usar val en todas partes y pasar a var solo cuando la reasignación es realmente necesaria.¿Cómo funciona el null safety en Kotlin?
String nunca puede contener null; String? sí. El compilador no te deja llamar a un método sobre un valor nullable sin tratar el caso null: con una llamada segura (s?.length), un valor por defecto con Elvis (s?.length ?: 0), una comprobación de nulo con smart cast (if (s != null)) o, como último recurso, la aserción de no nulo s!!, que lanza una NullPointerException si el valor es realmente null.¿Cuándo debo usar when en lugar de if en Kotlin?
when siempre que compares un valor contra varias posibilidades (constantes, rangos, tipos o una mezcla) y usa if/else para una única condición de sí o no. Ambos son expresiones, así que val label = when (x) { ... } y val label = if (c) a else b son idiomáticos. Un when usado como expresión debe ser exhaustivo, lo que normalmente significa añadir una rama else (las sealed classes y los enums pueden serlo sin ella).¿Puedo practicar Kotlin online?
when, bucles, funciones y colecciones, y emite un certificado gratuito al final.