Un poco de historia
Interés por Kotlin - Google Trends
¿Qué es Kotlin?
El compilador de Kotlin (kotlinc)
TODO es un objeto
package kotlin
/**
* The root of the Kotlin class hierarchy. Every Kotlin class has [Any] as a superclass.
*/
public open class Any {
public open operator fun equals(other: Any?): Boolean
public open fun hashCode(): Int
public open fun toString(): String
}
Tipos de dato e Inmutabilidad
val pi = 3.14159265358 //Su valor no puede cambiar
var radio = 4
var diametro: Double = 0.0 //Se puede cambiar después
diametro = radio * 2.0
Java | Kotlin |
---|---|
int | Int |
double | Double |
boolean | Boolean |
Java | Kotlin |
---|---|
Integer | Int? |
Double | Double? |
Boolean | Boolean? |
Primitivos
Objetos
Funciones Kotlin
class Calculadora {
fun suma(num1: Double, num2: Double): Double {
return num1 + num2
}
fun resta(num1: Double, num2: Double): Double = num1 - num2
}
Modificadores de visibilidad
Modificador | Visibilidad |
---|---|
private | A nivel de archivo |
internal | Mismo módulo |
Por defecto las clases y miembros de clase son public
Nivel superior
Modificador | Visibilidad |
---|---|
private | A nivel de la clase |
internal | Mismo módulo |
protected | Clases y subclases |
Nivel de clase
Modificadores de acceso
Las clases son...
open/*final*/ class Mascota() {
fun caminar() {
println("Caminando...")
}
}
class Perro(): Mascota() {
init {
caminar()
}
}
Null Safety ( ?, .?, !!, ?: )
var a: String = "abc"
a = null // error de compilación
var a: String? = "abc"
a = null // ok
/*
* Si a es null el length
* también devolverá null
*/
val l = a?.length
/*
* Si a es null se lanzará
* un kotlin.KotlinNullPointerException
*/
val l = a!!.size
// Java
int l = a != null ? a.length : -1
// Kotlin (Operador Elvis)
val l = a?.length ?: -1
Not Null
Nullable ?
Acceder a Nullable ?.
Nullable obligatorio !!
Operador Elvis ?:
Cuidado con los Null Safety
java.lang.IllegalArgumentException: Parameter specified as non-null is null:
method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull
// Kotlin
class Mensaje {
//fun mostrar(text: String?) {
fun mostrar(text: String) { //java.lang.IllegalArgumentException
println("Text: $text")
}
}
// Java
public class Invoker {
public static void main(String[] args) {
new Mensaje().mostrar(null);
}
}
Error...
Expresiones
val a = "ABCD"
val l = if(a != null) a.length else -1
//a != null ? a.length : -1 No se puede usar
val l2 = when(a) {
null -> -1
else -> a.length
}
fun isNumeric(text: String): Boolean {
return try {
text.toDouble()
true
} catch(error: Exception) {
false
}
}
Data class
// Definición
data class Usuario (
var nombre: String,
var edad: Int,
var ciudad: String
)
// Uso del data class
val unUsuario = Usuario("Carlos", 30, "Cali")
Infiere:
Hereda de Any:
Parámetros nombrados y
valores por defecto
// Definición
data class Usuario (
var nombre: String,
var edad: Int,
var ciudad: String? = "Cali" // Definimos un valor por defecto
)
// Uso del data class
val usuario1 = Usuario("Carlos", 30)
val usuario2 = Usuario(nombre = "Carlos", edad = 30)
Con Kotlin podemos olvidarnos de tener que sobrecargar constructores o funciones
Template string
// Valor
val saludo = "Hola $nombre"
// Expresión
println("$saludo, tu nombre tiene ${nombre.length} caracteres")
// Multilinea
val info = """
Nombre: $nombre
Edad: $edad
Ciudad: $ciudad
"""
println(info)
Insertar variables directamente en la cadena (String) o incluso utilizar expresiones.
Property sintax
usuario.setNombre("Carlos Fernando")
println(usuario.getNombre())
De manera convencional con los get y set
usuario.nombre = "Carlos Fernando" // set
println(usuario.nombre) // get
Utilizando property sintax podemos omitir el uso explícito de las funciones set y get para simplemente asignar u obtener el valor el atributo de un objeto.
Con property sintax
Smart casting y Safe Cast operator
fun demo(a: Any) {
if (a is Array<*>) {
println(a[0]) // a es casteada a Array automáticamente
}
}
El compilador detecta cuando verificamos el tipo de una variable y realiza el cast automático en caso de ser necesario.
fun demo(y: Any?) {//Si y es un número?
val x: String? = y as? String
}
Funciones anónimas y Lambdas
// Lambdas
val x = 2.0
val sin = { n: Double -> Math.sin(n) }
val cos = { n: Double -> Math.cos(n) }
val r = (if(x > 1) sin else cos)(x)
println("R = $r")
//Función anónima
val toInSafety = fun(s: String): Int { return s.toIntOrNull() ?: 0 }
val s = "Carlos"
println("${toInSafety(s)}")
Funciones de extensión
Permite adicionar extender las funcionalidades de una clase sin modificarla
fun Date.toISODate(): String? {
return Constants.DEFAULT_DATE_FORMAT.format(this)
}
fun Date.toISOTime(withSeconds: Boolean = true): String? {
var formatedTime = Constants.DEFAULT_TIME_FORMAT.format(this)
if(!withSeconds) {
formatedTime = formatedTime.substring(0, formatedTime.lastIndexOf(":"))
}
return formatedTime
}
Collections
Collections
val colors = listOf("Rojo", "Amarillo", "Azul", "Rojo")
val colorsHex = mapOf("Amarillo" to "#123", "Azul" to "#456", "Rojo" to "#789")
fun main(args: Array<String>) {
val unitHex = colors
.map { colorsHex[it] }
.toSet()
println(unitHex)
}
Rangos 1..10 y Progresiones
Permite adicionar extender las funcionalidades de una clase sin modificarla
fun Date.toISODate(): String? {
return Constants.DEFAULT_DATE_FORMAT.format(this)
}
fun Date.toISOTime(withSeconds: Boolean = true): String? {
var formatedTime = Constants.DEFAULT_TIME_FORMAT.format(this)
if(!withSeconds) {
formatedTime = formatedTime.substring(0, formatedTime.lastIndexOf(":"))
}
return formatedTime
}
Delegados
class User(val map: Map<String, Any?>) {
val name: String by map
val age: Int by map
}
val user = User(mapOf(
"name" to "John Doe",
"age" to 25
))
import kotlin.properties.Delegates
class User {
var name: String by Delegates.observable("<no name>") {
prop, old, new ->
println("$old -> $new")
}
}
fun main() {
val user = User()
user.name = "first"
user.name = "second"
}
Corutinas
import kotlinx.coroutines.*
fun main() = runBlocking {
launch { doWorld() }
println("Hello,")
}
// this is your first suspending function
suspend fun doWorld() {
delay(1000L)
println("World!")
}
🤓 Mantén un pensamiento al rededor de lo básico
🐢 Empieza despacio pero hazlo real
😵 No intentes aprender todo el lenguaje de una vez
🔀 Aprende del convertidor automático
🤔 Cuestiona todos tus hábitos de Java
🏕️ Deja el parque más limpio de lo que lo encontraste
👴🏻 Frenar el entusiasmo
💸 No olvides a tus clientes
// Por Dan Kim