Kotlin, en profundidad
Una masterclass de Kotlin desde cero: esenciales → OOP → corrutinas → flows → sistema de tipos avanzado. 47 lecciones en 5 capítulos, con Kotlin 1.8.20 ejecutable en vivo, visualizaciones inline, callouts (pitfall/deeper/tip/FAQ) y práctica graduada vía stdin/stdout.
Aprendamos juntos.
Pregúntame sobre este curso o por dónde empezar.
Hola Kotlin → plantillas de strings → Int → división entera → val/var → punto flotante → familia de enteros → expresiones if/when → Char → capstone del recibo
- Paso 1
Hola, Kotlin — tu primer programa
Todo programa en Kotlin arranca en una única función: `fun main()`. Cuando ejecutás un archivo, la JVM encuentra `main` …
Empezar lección - Paso 2
Cadenas, caracteres especiales y plantillas
Una **cadena** (string) es texto entre comillas dobles: `"hello"`. Algunos caracteres no se pueden escribir literalmente…
Empezar lección - Paso 3
Números enteros — el tipo Int
`Int` es el tipo por defecto de Kotlin para números enteros. Es un entero con signo de 32 bits, así que admite valores d…
Empezar lección - Paso 4
División entera y el truco del módulo
Acá está la trampa en la que cae todo el mundo: cuando ambos operandos son `Int`, `/` hace **división entera** — descart…
Empezar lección - Paso 5
val vs var — inmutabilidad por defecto
Kotlin te da dos formas de ponerle nombre a un valor. `val` (de *value*) es una referencia de **solo lectura**: la asign…
Empezar lección - Paso 6
Números de punto flotante — Double y Float
Para números con parte fraccionaria, Kotlin usa **`Double`** (64 bits) por defecto y **`Float`** (32 bits) cuando lo ped…
Empezar lección - Paso 7
La familia de enteros — Long, Int, Short, Byte
`Int` no es el único tipo de número entero. Kotlin tiene cuatro tipos enteros con signo de distintos anchos: **`Byte`** …
Empezar lección - Paso 8
if y when son expresiones
En muchos lenguajes, `if` es una *sentencia*: hace algo, pero no produce ningún valor. En Kotlin, **`if` es una expresió…
Empezar lección - Paso 9
El tipo Char
Un **`Char`** es un único carácter entre comillas **simples**: `'A'`, `'7'`, `'\n'`. No lo confundas con un `String` de …
Empezar lección - Paso 10
Proyecto integrador — una impresora de recibos
Es hora de combinar todo el capítulo. Ya conociste `main`, las plantillas de cadena, `Int` y `Double`, la división enter…
Empezar lección
Rangos → bucles for/while → coincidencia con when → listas, mapas y sets → iteración → operaciones sobre colecciones.
- Paso 11
Bucles — repeat y while
Un **bucle** ejecuta un bloque de código más de una vez. El más simple de Kotlin es **`repeat(n) { ... }`**: ejecuta el …
Empezar lección - Paso 12
El bucle for y los rangos
El bucle **`for`** de Kotlin recorre cualquier cosa que se pueda *iterar*: un rango, una lista, una cadena. No existe el…
Empezar lección - Paso 13
Rangos, downTo y step
Los rangos dan para mucho más que `a..b`. **`downTo`** cuenta hacia atrás: `5 downTo 1` es `5,4,3,2,1`. **`step`** cambi…
Empezar lección - Paso 14
do-while y cómo dividir la entrada
Un bucle **`do { ... } while (cond)`** es la imagen espejo de `while`: ejecuta el cuerpo *primero* y después comprueba l…
Empezar lección - Paso 15
Listas — lo básico de solo lectura
Una **`List`** es una colección ordenada de elementos. Creala con **`listOf(...)`**: `val xs = listOf(10, 20, 30)`. El t…
Empezar lección - Paso 16
MutableList — agregar, quitar, modificar
Cuando de verdad necesitás agrandar, achicar o editar una colección, usá una **`MutableList`**, creada con **`mutableLis…
Empezar lección - Paso 17
Iterar con índice y valor
A menudo necesitás un elemento *y* su posición: para numerar un menú, dar formato a una tabla o comparar vecinos. **`lis…
Empezar lección - Paso 18
break y continue
Hay dos palabras clave que dirigen un bucle desde adentro. **`break`** sale del bucle de inmediato: no hay más iteracion…
Empezar lección - Paso 19
Bucles anidados
Un **bucle anidado** es un bucle dentro de otro bucle. Por cada pasada del bucle exterior, el bucle interior se ejecuta …
Empezar lección - Paso 20
Proyecto integrador — FizzBuzz
**FizzBuzz** es el ejercicio corto de programación más famoso, y un cierre perfecto para el flujo de control. Las reglas…
Empezar lección
Clases, constructores, propiedades, métodos y visibilidad — los pilares de los objetos en Kotlin.
- Paso 21
Clases y objetos
Una **clase** es un plano que agrupa **estado** (propiedades) y **comportamiento** (funciones) en un único tipo con nomb…
Empezar lección - Paso 22
Funciones y cuerpos de expresión
Una **función** es un bloque de comportamiento reutilizable y con nombre: `fun square(n: Int): Int { return n * n }`. Su…
Empezar lección - Paso 23
Parámetros, valores por defecto y argumentos con nombre
Las funciones pueden recibir **varios parámetros**, separados por comas: `fun rectArea(width: Int, height: Int) = width …
Empezar lección - Paso 24
this y llamadas a métodos
Dentro de una clase, **`this`** hace referencia a la instancia actual: el objeto concreto sobre el que se llamó el métod…
Empezar lección - Paso 25
Constructores primarios e init
El **constructor primario** forma parte de la cabecera de la clase. `class Account(val owner: String, var balance: Int)`…
Empezar lección - Paso 26
Constructores secundarios
A veces una clase necesita **más de una forma de construirse**. Un **constructor secundario**, declarado en el cuerpo co…
Empezar lección - Paso 27
Funciones miembro y encapsulamiento
Las **funciones miembro** (métodos) son donde vive el comportamiento de una clase. Leen y modifican las propiedades de l…
Empezar lección - Paso 28
Tipos de retorno, Unit y varios return
El **tipo de retorno** de una función se declara después de la lista de parámetros: `fun max3(a: Int, b: Int, c: Int): I…
Empezar lección - Paso 29
Propiedades y valores por defecto
Una **propiedad** es el estado de una clase. Ya sea que la declares en el constructor primario (`val`/`var`) o en el cue…
Empezar lección - Paso 30
Proyecto integrador — BankAccount
Es hora de combinar el capítulo en una sola clase bien encapsulada. Una **`BankAccount`** guarda un `balance` y expone d…
Empezar lección
open/override, clases abstractas, interfaces y despacho polimórfico en Kotlin.
- Paso 31
Funciones inline: la reescritura en el punto de llamada
Una función de orden superior que recibe una lambda normalmente *tiene un costo* en runtime: la lambda se convierte en u…
Empezar lección - Paso 32
reified: cómo vencer el borrado de tipos
En la JVM, los genéricos se **borran**: en runtime, una `List<String>` y una `List<Int>` son simplemente `List`, y dentr…
Empezar lección - Paso 33
value classes: envoltorios sin envoltorio
Muchas veces querés un *tipo* sin un *costo*: un `UserId` que en realidad es un `Int` pero que no se pueda confundir con…
Empezar lección - Paso 34
Varianza: out, in y proyecciones estrella
Los genéricos plantean una pregunta sutil: si `Cat` es un `Animal`, ¿`List<Cat>` es una `List<Animal>`? A primera vista …
Empezar lección - Paso 35
Smart casts: estrechamiento de tipos por flujo de control
En muchos lenguajes, después de comprobar `if (x is String)` igual tenés que *castear*: `((String) x).length`. Kotlin si…
Empezar lección - Paso 36
Contratos: enseñarle al analizador de flujo
El análisis de flujo detrás de los smart casts es potente pero *local*: solo ve el código que puede leer directamente. S…
Empezar lección - Paso 37
Delegación: en qué se traduce `by`
La herencia es una forma de reutilizar comportamiento, pero te acopla fuertemente a una superclase. La **delegación** ('…
Empezar lección - Paso 38
Delegación de propiedades: getValue, setValue, provideDelegate
`val name by lazy { compute() }` y `var x by Delegates.observable(...)` usan el *otro* `by`: la **delegación de propieda…
Empezar lección - Paso 39
tailrec: recursión compilada a un bucle
La recursión es elegante pero peligrosa en la JVM: cada llamada consume un marco de pila (stack frame), y a unos pocos m…
Empezar lección - Paso 40
Data classes: equals, hashCode, copy, componentN
Marcá una clase como **`data`** y el compilador genera, a partir de las propiedades del **constructor primario**, el boi…
Empezar lección
Lectura y escritura de archivos, pipelines de colecciones más ricos y refactoring que preserva el comportamiento.
- Paso 41
Corrutinas por dentro: la máquina de estados de suspend
Una función `suspend` parece *bloquearse* y reanudarse, pero la JVM no tiene ninguna forma nativa de pausar un método a …
Empezar lección - Paso 42
Sealed classes y when exhaustivo
Una clase (o interfaz) **`sealed`** declara un conjunto **cerrado** de subtipos: cada subclase directa tiene que declara…
Empezar lección - Paso 43
Funciones de extensión y receptores
Una **función de extensión** te permite agregarle un método a un tipo que no es tuyo (`String`, `List`, una clase de una…
Empezar lección - Paso 44
Scope functions: let, run, with, apply, also
Las cinco **scope functions** (`let`, `run`, `with`, `apply`, `also`) ejecutan una lambda *en el contexto de un objeto*.…
Empezar lección - Paso 45
Sequences: pipelines perezosos, elemento por elemento
Encadenar `map`/`filter` sobre una **`List`** es **ansioso** (eager): cada operación se ejecuta completa sobre toda la c…
Empezar lección - Paso 46
Null safety: ?., ?:, !! y let
Kotlin divide cada tipo en **no nulo** (`String`) y **anulable** (`String?`). Un tipo no nulo *no puede* contener `null`…
Empezar lección - Paso 47
Enum classes: constantes con estado y comportamiento
Una **`enum class`** define un conjunto fijo y finito de instancias constantes con nombre (`Direction.NORTH`, `Direction…
Empezar lección