Kotlin Es.34
Kotlin Es.34
Kotlin Es.34
#kotlin
Tabla de contenido
Acerca de 1
Observaciones 2
Compilando kotlin 2
Versiones 2
Examples 3
Hola Mundo 3
Examples 7
Capítulo 3: Anotaciones 8
Examples 8
Meta-anotaciones 8
Capítulo 4: Arrays 10
Examples 10
Arreglos Genéricos 10
Arreglos de primitivos 10
Extensiones 11
Iterar Array 11
Observaciones 13
Examples 13
Mientras bucles 14
Romper y continuar 14
Recursion 15
Capítulo 6: Colecciones 16
Introducción 16
Sintaxis 16
Examples 16
Usando la lista 16
Usando el mapa 16
Usando set 16
Examples 17
Configuracion gradle 17
JVM de orientación 17
Apuntando a android 17
Apuntando a js 17
Instalar el complemento 18
Configurar un proyecto 18
Convertir Java 18
Capítulo 8: coroutines 21
Introducción 21
Examples 21
Observaciones 22
Examples 22
Declaración if estándar 22
Introducción 26
Examples 26
Introducción 27
Examples 27
Observaciones 29
Examples 29
Inicialización 29
Enumeración simple 30
Mutabilidad 30
Introducción 31
Observaciones 31
Sobre la pereza 31
Reutilizando corrientes 32
Ver también: 32
Examples 33
Diferentes tipos de transmisiones # 4: iterar una matriz, mapear los valores, calcular el 35
Diferentes tipos de flujos n. ° 5: iterar perezosamente una lista de cadenas, mapear los v 35
Diferentes tipos de flujos n. ° 6: iteren perezosamente un flujo de Ints, mapee los valore 36
Cómo funcionan las secuencias - filtre, mayúsculas, luego ordene una lista 37
Recopile el ejemplo # 5: encuentre personas mayores de edad, una cadena con formato de sal 37
Reúna el ejemplo # 6: agrupe a las personas por edad, edad de impresión y nombres juntos 38
Examples 42
Introducción 43
Examples 43
Configuración 43
Usando vistas 43
Sintaxis 46
Parámetros 46
Examples 46
Funciones Lambda 47
Referencias de funciones 48
Funciones básicas 49
Funciones abreviadas 49
Funciones en línea 50
Introducción 51
Observaciones 51
Examples 51
Ejemplos basicos 51
Introducción 53
Examples 53
función downTo () 53
función de paso 53
hasta la función 53
Introducción 54
Sintaxis 54
Parámetros 54
Observaciones 54
Examples 55
Introducción 57
Sintaxis 57
Parámetros 57
Examples 57
Usando la subclase: 58
Métodos de anulación: 59
Examples 60
Elementos de cuerda 60
Literales de cuerda 60
Plantillas de cadena 61
Igualdad de cuerdas 61
Observaciones 63
Examples 63
Interfaz básica 63
Propiedades 63
Implementaciones multiples 64
Propiedades en interfaces 64
Conflictos al implementar múltiples interfaces con implementaciones predeterminadas 65
Examples 67
Reglas 67
Introducción 68
Examples 68
Declarando variables 68
Hechos rápidos 68
Igualdad e identidad 69
Sintaxis 70
Observaciones 70
Examples 71
Observaciones 72
Examples 72
kotlin.logging 72
Sintaxis 73
Observaciones 73
Examples 73
Muestra que se extiende por mucho tiempo para representar una cadena humana legible 74
Extensiones 77
Uso 77
Introducción 78
Sintaxis 78
Examples 78
Ejemplo de código 78
Examples 79
Introducción 83
Examples 83
Sintaxis 85
Examples 85
Introducción 87
Examples 87
Inicialización perezosa 87
Propiedades observables 87
Delegación personalizada 87
Delegado Se puede usar como una capa para reducir la placa de caldera 88
Introducción 90
Examples 90
Introducción 92
Observaciones 92
Examples 92
Examples 96
La clase RegEx 97
Examples 101
Afirmación 103
Introducción 104
Sintaxis 104
Observaciones 104
Examples 104
Observaciones 105
Examples 105
Creditos 107
Acerca de
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: kotlin
It is an unofficial and free Kotlin ebook created for educational purposes. All the content is
extracted from Stack Overflow Documentation, which is written by many hardworking individuals at
Stack Overflow. It is neither affiliated with Stack Overflow nor official Kotlin.
The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.
Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to [email protected]
https://riptutorial.com/es/home 1
Capítulo 1: Empezando con Kotlin
Observaciones
Kotlin es un lenguaje de programación orientado a objetos de tipo estático desarrollado por
JetBrains que se dirige principalmente a la JVM. Kotlin se ha desarrollado con el objetivo de ser
rápido de compilar, compatible con versiones anteriores, muy seguro para el tipo, y 100%
interoperable con Java. Kotlin también se ha desarrollado con el objetivo de proporcionar muchas
de las funciones que buscan los desarrolladores de Java. El compilador estándar de Kotlin
permite compilarlo tanto en el bytecode de Java para la JVM como en JavaScript.
Compilando kotlin
Kotlin tiene un complemento IDE estándar para Eclipse e IntelliJ. Kotlin también se puede
compilar usando Maven , usando Ant y usando Gradle , o por medio de la línea de comandos .
Vale la pena señalar que en $ kotlinc Main.kt generará un archivo de clase java, en este caso
MainKt.class ( MainKt.class cuenta que el Kt se adjunta al nombre de la clase). Sin embargo, si
uno fuera a ejecutar el archivo de clase utilizando $ java MainKt java se lanzará la siguiente
excepción:
Para ejecutar el archivo de clase resultante utilizando Java, se debe incluir el archivo jar de
tiempo de ejecución Kotlin en la ruta de la clase actual.
Versiones
1.0.0 2016-02-15
1.0.1 2016-03-16
1.0.2 2016-05-13
1.0.3 2016-06-30
https://riptutorial.com/es/home 2
Versión Fecha de lanzamiento
1.0.4 2016-09-22
1.0.5 2016-11-08
1.0.6 2016-12-27
1.1.0 2017-03-01
1.1.1 2017-03-14
1.1.2 2017-04-25
1.1.3 2017-06-23
Examples
Hola Mundo
Todos los programas de Kotlin comienzan en la función main . Aquí hay un ejemplo de un
programa simple "Hello World" de Kotlin:
package my.program
Cuando se dirige a la JVM, la función se compilará como un método estático en una clase con un
nombre derivado del nombre de archivo. En el ejemplo anterior, la clase principal a ejecutar sería
my.program.MainKt .
Para cambiar el nombre de la clase que contiene funciones de nivel superior para un archivo en
particular, coloque la siguiente anotación en la parte superior del archivo sobre la declaración del
paquete:
@file:JvmName("MyApp")
Ver también:
https://riptutorial.com/es/home 3
Hola mundo usando una declaración de objeto
Alternativamente, puede usar una Declaración de Objeto que contiene la función principal para un
programa Kotlin.
package my.program
object App {
@JvmStatic fun main(args: Array<String>) {
println("Hello World")
}
}
La ventaja de este método sobre una función de nivel superior es que el nombre de la clase que
se ejecutará es más evidente, y cualquier otra función que agregue se incluye en la App la clase.
También tiene una instancia única de la App para almacenar el estado y hacer otro trabajo.
Ver también:
Similar a usar una Declaración de Objeto, puede definir la función main de un programa Kotlin
usando un Objeto Acompañante de una clase.
package my.program
class App {
companion object {
@JvmStatic fun main(args: Array<String>) {
println("Hello World")
}
}
}
La ventaja de este método sobre una función de nivel superior es que el nombre de la clase que
se ejecutará es más evidente, y cualquier otra función que agregue se incluye en la App la clase.
Esto es similar al ejemplo de la Object Declaration , aparte de que usted tiene el control de crear
instancias de cualquier clase para realizar un trabajo adicional.
Una pequeña variación que crea una instancia de la clase para hacer el "hola" real:
class App {
companion object {
@JvmStatic fun main(args: Array<String>) {
App().run()
}
https://riptutorial.com/es/home 4
}
fun run() {
println("Hello World")
}
}
Ver también:
Todos estos estilos de métodos principales también se pueden usar con varargs :
package my.program
Como Java, proporcione dos comandos diferentes para compilar y ejecutar código Java. Igual que
Kotlin también te proporcionan diferentes comandos.
javac para compilar archivos java. java para ejecutar archivos java.
Igual que kotlinc para compilar archivos kotlin para ejecutar archivos kotlin.
Los argumentos pasados desde la consola se pueden recibir en el programa Kotlin y se pueden
usar como entrada. Puede pasar N (1 2 3 y así sucesivamente) números de argumentos desde el
símbolo del sistema.
https://riptutorial.com/es/home 5
a
} else {
println("The value of b is $b")
b
}
return max;
Aquí, ingrese dos números desde la línea de comando para encontrar el número máximo. Salida:
The value of b is 89
Max number is: 89
https://riptutorial.com/es/home 6
Capítulo 2: Advertencias de Kotlin
Examples
Llamando a un toString () en un tipo anulable
Una cosa a tener en cuenta cuando se utiliza el método toString en Kotlin es el manejo de null en
combinación con el String? .
// Incorrect:
val text = view.textField?.text.toString() ?: ""
Se esperaría que si el campo no existiera, el valor fuera una cadena vacía, pero en este caso es
"null" .
// Correct:
val text = view.textField?.text?.toString() ?: ""
https://riptutorial.com/es/home 7
Capítulo 3: Anotaciones
Examples
Declarar una anotación
Las anotaciones son medios para adjuntar metadatos al código. Para declarar una anotación,
coloque el modificador de anotación delante de una clase:
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION,
AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION)
annotation class Strippable
• tipos que corresponden a los tipos primitivos de Java (Int, Long, etc.);
• instrumentos de cuerda
• clases (Foo :: clase)
• enums
• otras anotaciones
• matrices de los tipos enumerados anteriormente
Meta-anotaciones
Al declarar una anotación, se puede incluir metainformación utilizando las siguientes meta-
anotaciones:
• @Target : especifica los posibles tipos de elementos que se pueden anotar con la anotación
(clases, funciones, propiedades, expresiones, etc.)
https://riptutorial.com/es/home 8
Ejemplo:
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION,
AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION)
@Retention(AnnotationRetention.SOURCE)
@MustBeDocumented
annotation class Fancy
https://riptutorial.com/es/home 9
Capítulo 4: Arrays
Examples
Arreglos Genéricos
Para crear una matriz con un tamaño dado y valores iniciales, use el constructor:
strings.set(2, "ChangedItem")
print(strings.get(2)) // prints "ChangedItem"
Arreglos de primitivos
Estos tipos no se heredan de Array<T> para evitar el boxeo, sin embargo, tienen los mismos
atributos y métodos.
https://riptutorial.com/es/home 10
Extensiones
average() se define para Byte , Int , Long , Short , Double , Float y siempre devuelve Double :
getOrNull(index: Int) devuelve nulo si el índice está fuera de los límites, de lo contrario, un
elemento de la matriz
first() , last()
min() , max()
Iterar Array
Puede imprimir los elementos de la matriz utilizando el bucle igual que el bucle mejorado de Java,
pero necesita cambiar la palabra clave de : a in .
https://riptutorial.com/es/home 11
val a = Array(3) { i -> i * 2 } // creates an Array<Int> of size 3 containing [0, 2, 4]
La matriz devuelta siempre tendrá un tipo anulable. Las matrices de elementos no anulables no
se pueden crear sin inicializar.
https://riptutorial.com/es/home 12
Capítulo 5: Bucles en Kotlin
Observaciones
En Kotlin, los bucles se compilan en bucles optimizados siempre que sea posible. Por ejemplo, si
recorre un rango de números, el código de bytes se compilará en un bucle correspondiente
basado en valores int simples para evitar la sobrecarga de creación de objetos.
Examples
Repetir una acción x veces.
repeat(10) { i ->
println("This line will be printed 10 times")
println("We are on the ${i + 1}. loop iteration")
}
Puede realizar un bucle sobre cualquier iterable utilizando el bucle for estándar:
for(i in 0..9) {
print(i)
}
También hay un enfoque funcional para iterar incluido en la biblioteca estándar, sin
construcciones de lenguaje aparentes, utilizando la función forEach:
iterable.forEach {
print(it.toString())
}
it en este ejemplo dispone implícitamente el elemento actual, ver las funciones lambda
https://riptutorial.com/es/home 13
Mientras bucles
while(condition) {
doSomething()
}
do {
doSomething()
} while (condition)
Romper y continuar
Romper y continuar las palabras clave funcionan como lo hacen en otros idiomas.
while(true) {
if(condition1) {
continue // Will immediately start the next iteration, without executing the rest of
the loop body
}
if(condition2) {
break // Will exit the loop completely
}
}
Si tiene bucles anidados, puede etiquetar las sentencias de bucle y calificar las sentencias de
interrupción y continuación para especificar qué bucle desea continuar o dividir:
https://riptutorial.com/es/home 14
Recursion
También es posible realizar bucles a través de la recursión en Kotlin como en la mayoría de los
lenguajes de programación.
println(factorial(10)) // 3628800
En el ejemplo anterior, la función factorial se llamará repetidamente por sí misma hasta que se
cumpla la condición dada.
La biblioteca estándar de Kotlin también proporciona numerosas funciones útiles para trabajar
iterativamente sobre colecciones.
Por ejemplo, la función de map se puede utilizar para transformar una lista de elementos.
Una de las muchas ventajas de este estilo es que permite encadenar operaciones de manera
similar. Solo se requeriría una pequeña modificación si, por ejemplo, la lista anterior fuera
necesaria para ser filtrada para números pares. La función de filter puede ser utilizada.
https://riptutorial.com/es/home 15
Capítulo 6: Colecciones
Introducción
A diferencia de muchos idiomas, Kotlin distingue entre colecciones mutables e inmutables (listas,
conjuntos, mapas, etc.). El control preciso sobre cuándo se pueden editar las colecciones es útil
para eliminar errores y para diseñar buenas API.
Sintaxis
• listOf, mapOf y setOf devuelve objetos de solo lectura que no puede agregar ni eliminar
elementos.
• Si desea agregar o eliminar elementos, tiene que usar arrayListOf, hashMapOf, hashSetOf,
linkedMapOf (LinkedHashMap), linkedSetOf (LinkedHashSet), mutableListOpp una
colección de personas de la empresa. ), sortedMapOf o sortedSetOf
• Cada colección tiene métodos como las funciones first (), last (), get () y lambda, como
filtrar, mapear, unir, reducir y muchos otros.
Examples
Usando la lista
Usando el mapa
Usando set
https://riptutorial.com/es/home 16
Capítulo 7: Configurando la compilación de
Kotlin
Examples
Configuracion gradle
kotlin-gradle-pluginse usa para compilar el código Kotlin con Gradle. Básicamente, su versión
debe corresponder a la versión de Kotlin que desea utilizar. Por ejemplo, si desea usar Kotlin
1.0.3 , también necesita aplicar kotlin-gradle-plugin versión 1.0.3 .
buildscript {
ext.kotlin_version = '1.0.3'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
Entonces necesitas aplicar este plugin a tu proyecto. La forma en que lo hace difiere cuando se
dirige a diferentes plataformas:
JVM de orientación
Apuntando a android
Apuntando a js
https://riptutorial.com/es/home 17
• Pruebas de kotlin: src/test/kotlin
• Pruebas de java: src/test/java
• recursos de tiempo de ejecución: src/main/resources
• recursos de prueba: src/test/resources
Es posible que deba configurar SourceSets si está utilizando un diseño de proyecto personalizado.
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
Instalar el complemento
Para instalar el complemento Kotlin, vaya a Archivo> Configuración> Editor> Complementos>
Instalar el complemento JetBrains ...> Kotlin> Instalar, luego reinicie Android Studio cuando se le
solicite.
Configurar un proyecto
Cree un proyecto de Android Studio normalmente, luego presione Ctrl + Shift + A. En el cuadro
de búsqueda, escriba "Configurar Kotlin en el proyecto" y presione Entrar.
Android Studio alterará sus archivos de Gradle para agregar todas las dependencias necesarias.
Convertir Java
Para convertir sus archivos Java a archivos Kotlin, presione Ctrl + Shift + A y busque "Convertir
archivo Java a archivo Kotlin". Esto cambiará la extensión del archivo actual a .kt y convertirá el
código a Kotlin.
https://riptutorial.com/es/home 18
Migración de Gradle usando el script Groovy al script Kotlin
Pasos:
• ahora abra Intellij y abra su proyecto, en la ventana del explorador, debe ser reconocido
como un proyecto de Gradle, si no, expréselo primero.
• después de abrir, deje que Intellij funcione, abra build.gradle.kts y verifique si hay algún
https://riptutorial.com/es/home 19
error. Si el resaltado no funciona y / o todo está marcado en rojo, cierre y vuelva a abrir
Intellij
Si está en Windows, puede encontrar este error , descargue la distribución completa de Gradle
3.3 y utilícela en su lugar. Relacionados .
Bono pequeño: si desea evitar todas las molestias de publicación en Maven y similares, use
Jitpack , las líneas para agregar son casi idénticas en comparación con Groovy. Puedes inspirarte
en este proyecto mío.
https://riptutorial.com/es/home 20
Capítulo 8: coroutines
Introducción
Ejemplos de implementación experimental (todavía) de Kotlin de coroutines
Examples
Coroutine simple que demora 1 segundo pero no bloquea.
resultado
Hello,
World!
https://riptutorial.com/es/home 21
Capítulo 9: Declaraciones condicionales
Observaciones
A diferencia del switch de Java, la instrucción when no tiene un comportamiento de caída. Esto
significa que, si una rama coincide, el flujo de control regresa después de su ejecución y no se
requiere una declaración de break . Si desea combinar los comportamientos para varios
argumentos, puede escribir varios argumentos separados por comas:
when (x) {
"foo", "bar" -> println("either foo or bar")
else -> println("didn't match anything")
}
Examples
Declaración if estándar
Tenga en cuenta que else -branch no es opcional si la declaración- if se usa como una
expresión.
Esto también se puede hacer con una variante multilínea con corchetes y múltiples declaraciones
else if .
https://riptutorial.com/es/home 22
CONSEJO: Kotlin puede inferir el tipo de variable para usted, pero si desea estar
seguro del tipo, simplemente anótelo en la variable como: val str: String = esto
forzará el tipo y hará que sea más fácil de leer.
La instrucción when es una alternativa a una instrucción if con varias sucursales else-if-branch:
when {
str.length == 0 -> print("The string is empty!")
str.length > 5 -> print("The string is short!")
else -> print("The string is long!")
}
if (str.length == 0) {
print("The string is empty!")
} else if (str.length > 5) {
print("The string is short!")
} else {
print("The string is long!")
}
Al igual que con la sentencia if, la rama else es opcional, y puede agregar tantas o tan pocas
ramas como desee. También puedes tener ramas multilínea:
when {
condition -> {
doSomething()
doSomeMore()
}
else -> doSomethingElse()
}
when (x) {
"English" -> print("How are you?")
"German" -> print("Wie geht es dir?")
else -> print("I don't know that language yet :(")
}
https://riptutorial.com/es/home 23
when (x) {
in names -> print("I know that name!")
!in 1..10 -> print("Argument was not in the range from 1 to 10")
is String -> print(x.length) // Due to smart casting, you can use String-functions here
}
Para ser utilizada como una expresión, la instrucción when debe ser exhaustiva, es decir, tener
una rama else o cubrir todas las posibilidades con las ramas de otra manera.
Como puede ver en la segunda línea de casos ( Monday y Tuedsay ), también es posible combinar
dos o más valores de enum .
Si sus casos no son exhaustivos, la compilación mostrará un error. Puedes usar else para
manejar casos predeterminados:
https://riptutorial.com/es/home 24
Day.Tuesday -> // Work hard
Day.Wednesday -> // ...
Day.Thursday -> //
Day.Friday -> //
else -> // Party on weekend
}
}
Aunque se puede hacer lo mismo usando la construcción if-then-else , when se cuida de los
valores de enum faltan y los hace más naturales.
Haga clic aquí para obtener más información sobre kotlin enum
https://riptutorial.com/es/home 25
Capítulo 10: Delegación de clase
Introducción
Una clase Kotlin puede implementar una interfaz delegando sus métodos y propiedades a otro
objeto que implementa esa interfaz. Esto proporciona una forma de componer el comportamiento
utilizando asociación en lugar de herencia.
Examples
Delegar un método a otra clase.
interface Foo {
fun example()
}
class Bar {
fun example() {
println("Hello, world!")
}
}
Baz(Bar()).example()
https://riptutorial.com/es/home 26
Capítulo 11: Edificio DSL
Introducción
Concéntrese en los detalles de sintaxis para diseñar DSL internos en Kotlin.
Examples
Infix enfoque para construir DSL
Si usted tiene:
@Test
fun test() {
100.plusOne() shouldBe 101
}
Si usted tiene:
Si usted tiene:
val r = Random(233)
infix inline operator fun Int.rem(block: () -> Unit) {
https://riptutorial.com/es/home 27
if (r.nextInt(100) < this) block()
}
Si usted tiene:
Si se siente confundido con shouldBe arriba, vea el ejemplo de Infix approach to build DSL .
https://riptutorial.com/es/home 28
Capítulo 12: Enumerar
Observaciones
Al igual que en Java, las clases de enumeración en Kotlin tienen métodos sintéticos que permiten
enumerar las constantes de enumeración definidas y obtener una constante de enumeración por
su nombre. Las firmas de estos métodos son las siguientes (asumiendo que el nombre de la clase
enum es EnumClass ):
Examples
Inicialización
Enumerar clases como cualquier otra clase puede tener un constructor y ser inicializado
Las clases de enumeración también pueden declarar miembros (es decir, propiedades y
funciones). Se debe colocar un punto y coma ( ; ) entre el último objeto de enumeración y la
primera declaración del miembro.
https://riptutorial.com/es/home 29
override val rgb: Int = 0xFF0000
},
GREEN {
override val rgb: Int = 0x00FF00
},
BLUE {
override val rgb: Int = 0x0000FF
}
Enumeración simple
Cada enum constante es un objeto. Las constantes enum están separadas por comas.
Mutabilidad
Las enumeraciones pueden ser mutables, esta es otra forma de obtener un comportamiento
singleton:
println(Planet.MARS) // MARS[population=0]
Planet.MARS.population = 3
println(Planet.MARS) // MARS[population=3]
https://riptutorial.com/es/home 30
Capítulo 13: Equivalentes de flujo de Java 8
Introducción
Kotlin proporciona muchos métodos de extensión en colecciones e iterables para aplicar
operaciones de estilo funcional. Un tipo de Sequence dedicado permite la composición perezosa de
varias de estas operaciones.
Observaciones
Sobre la pereza
Si desea procesar de forma perezosa una cadena, puede convertirla a una Sequence utilizando
asSequence() antes de la cadena. Al final de la cadena de funciones, normalmente también
terminas con una Sequence . Luego puede usar toList() , toSet() , toMap() o alguna otra función
para materializar la Sequence al final.
es lo mismo que:
Debido a que Kotlin sabe qué es la people , y que people.age es Int por lo tanto, la expresión de
filtro solo permite la comparación con un Int , y que people.name es una String por lo tanto, el paso
del map produce una List<String> ( List de String de solo lectura).
Ahora, si las people posiblemente fueran null , como en una List<People>? entonces:
https://riptutorial.com/es/home 31
Devuelve una List<String>? eso tendría que estar marcado con un valor nulo ( o usar uno de los
otros operadores de Kotlin para valores que aceptan valores nulos , vea esta forma idiomática de
Kotlin para tratar los valores que aceptan valores nulos y también la forma idiomática de manejar
una lista vacía o nula en Kotlin )
Reutilizando corrientes
En Kotlin, depende del tipo de colección si se puede consumir más de una vez. Una Sequence
genera un nuevo iterador cada vez y, a menos que afirme "usar solo una vez", se puede
restablecer al inicio cada vez que se actúe. Por lo tanto, mientras lo siguiente falla en la secuencia
de Java 8, pero funciona en Kotlin:
// Java:
Stream<String> stream =
Stream.of("d2", "a2", "b1", "b3", "c").filter(s -> s.startsWith("b"));
// Kotlin:
val stream = listOf("d2", "a2", "b1", "b3", "c").asSequence().filter { it.startsWith('b' ) }
stream.forEach(::println) // b1, b2
stream.forEach(::println) // b1, b2
// Java:
Supplier<Stream<String>> streamSupplier =
() -> Stream.of("d2", "a2", "b1", "b3", "c")
.filter(s -> s.startsWith("a"));
Por lo tanto, en Kotlin, el proveedor de los datos decide si se puede restablecer y proporcionar un
nuevo iterador o no. Pero si desea restringir intencionalmente una Sequence a una iteración de
tiempo, puede usar la función constrainOnce() para la Sequence siguiente manera:
stream.forEach(::println) // b1, b2
stream.forEach(::println) // Error:java.lang.IllegalStateException: This sequence can be
consumed only once.
Ver también:
https://riptutorial.com/es/home 32
• Referencia de API para funciones de extensión para Iterable
• Referencia de API para funciones de extensión para Array
• Referencia de API para funciones de extensión para Lista
• Referencia de API para funciones de extensión a Map
Examples
Acumular nombres en una lista
// Java:
List<String> list = people.stream().map(Person::getName).collect(Collectors.toList());
// Kotlin:
val list = people.map { it.name } // toList() not needed
// Java:
String joined = things.stream()
.map(Object::toString)
.collect(Collectors.joining(", "));
// Kotlin:
val joined = things.joinToString() // ", " is used as separator, by default
// Java:
int total = employees.stream()
.collect(Collectors.summingInt(Employee::getSalary)));
// Kotlin:
val total = employees.sumBy { it.salary }
// Java:
Map<Department, List<Employee>> byDept
= employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment));
// Kotlin:
val byDept = employees.groupBy { it.department }
// Java:
https://riptutorial.com/es/home 33
Map<Department, Integer> totalByDept
= employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment,
Collectors.summingInt(Employee::getSalary)));
// Kotlin:
val totalByDept = employees.groupBy { it.dept }.mapValues { it.value.sumBy { it.salary }}
// Java:
Map<Boolean, List<Student>> passingFailing =
students.stream()
.collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
// Kotlin:
val passingFailing = students.partition { it.grade >= PASS_THRESHOLD }
// Java:
List<String> namesOfMaleMembersCollect = roster
.stream()
.filter(p -> p.getGender() == Person.Sex.MALE)
.map(p -> p.getName())
.collect(Collectors.toList());
// Kotlin:
val namesOfMaleMembers = roster.filter { it.gender == Person.Sex.MALE }.map { it.name }
// Java:
Map<Person.Sex, List<String>> namesByGender =
roster.stream().collect(
Collectors.groupingBy(
Person::getGender,
Collectors.mapping(
Person::getName,
Collectors.toList())));
// Kotlin:
val namesByGender = roster.groupBy { it.gender }.mapValues { it.value.map { it.name } }
// Java:
List<String> filtered = items.stream()
.filter( item -> item.startsWith("o") )
.collect(Collectors.toList());
https://riptutorial.com/es/home 34
// Kotlin:
val filtered = items.filter { item.startsWith('o') }
// Java:
String shortest = items.stream()
.min(Comparator.comparing(item -> item.length()))
.get();
// Kotlin:
val shortest = items.minBy { it.length }
// Java:
Stream.of("a1", "a2", "a3")
.findFirst()
.ifPresent(System.out::println);
// Kotlin:
sequenceOf("a1", "a2", "a3").firstOrNull()?.apply(::println)
// Java:
IntStream.range(1, 4).forEach(System.out::println);
// Java:
Arrays.stream(new int[] {1, 2, 3})
.map(n -> 2 * n + 1)
.average()
.ifPresent(System.out::println); // 5.0
// Kotlin:
arrayOf(1,2,3).map { 2 * it + 1}.average().apply(::println)
https://riptutorial.com/es/home 35
// Java:
Stream.of("a1", "a2", "a3")
.map(s -> s.substring(1))
.mapToInt(Integer::parseInt)
.max()
.ifPresent(System.out::println); // 3
// Kotlin:
sequenceOf("a1", "a2", "a3")
.map { it.substring(1) }
.map(String::toInt)
.max().apply(::println)
// Java:
IntStream.range(1, 4)
.mapToObj(i -> "a" + i)
.forEach(System.out::println);
// a1
// a2
// a3
// Java:
Stream.of(1.0, 2.0, 3.0)
.mapToInt(Double::intValue)
.mapToObj(i -> "a" + i)
.forEach(System.out::println);
// a1
// a2
// a3
// Kotlin:
sequenceOf(1.0, 2.0, 3.0).map(Double::toInt).map { "a$it" }.forEach(::println)
// Java:
long count = items.stream().filter( item -> item.startsWith("t")).count();
// Kotlin:
val count = items.filter { it.startsWith('t') }.size
https://riptutorial.com/es/home 36
// but better to not filter, but count with a predicate
val count = items.count { it.startsWith('t') }
Cómo funcionan las secuencias - filtre, mayúsculas, luego ordene una lista
// Java:
List<String> myList = Arrays.asList("a1", "a2", "b1", "c2", "c1");
myList.stream()
.filter(s -> s.startsWith("c"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
// C1
// C2
// Kotlin:
val list = listOf("a1", "a2", "b1", "c2", "c1")
list.filter { it.startsWith('c') }.map (String::toUpperCase).sorted()
.forEach (::println)
// Java:
Arrays.asList("a1", "a2", "a3")
.stream()
.findFirst()
.ifPresent(System.out::println);
// Kotlin:
listOf("a1", "a2", "a3").firstOrNull()?.apply(::println)
// Kotlin:
inline fun String?.ifPresent(thenDo: (String)->Unit) = this?.apply { thenDo(this) }
https://riptutorial.com/es/home 37
con formato de salida
// Java:
String phrase = persons
.stream()
.filter(p -> p.age >= 18)
.map(p -> p.name)
.collect(Collectors.joining(" and ", "In Germany ", " are of legal age."));
System.out.println(phrase);
// In Germany Max and Peter and Pamela are of legal age.
// Kotlin:
val phrase = persons
.filter { it.age >= 18 }
.map { it.name }
.joinToString(" and ", "In Germany ", " are of legal age.")
println(phrase)
// In Germany Max and Peter and Pamela are of legal age.
Y como nota al margen, en Kotlin podemos crear clases de datos simples y crear una instancia de
los datos de prueba de la siguiente manera:
// Kotlin:
// data class has equals, hashcode, toString, and copy methods automagically
data class Person(val name: String, val age: Int)
// Java:
Map<Integer, String> map = persons
.stream()
.collect(Collectors.toMap(
p -> p.age,
p -> p.name,
(name1, name2) -> name1 + ";" + name2));
System.out.println(map);
// {18=Max, 23=Peter;Pamela, 12=David}
Ok, un caso más de interés aquí para Kotlin. Primero, las respuestas incorrectas para explorar las
variaciones de la creación de un Map partir de una colección / secuencia:
// Kotlin:
val map1 = persons.map { it.age to it.name }.toMap()
println(map1)
// output: {18=Max, 23=Pamela, 12=David}
// Result: duplicates overridden, no exception similar to Java 8
https://riptutorial.com/es/home 38
val map2 = persons.toMap({ it.age }, { it.name })
println(map2)
// output: {18=Max, 23=Pamela, 12=David}
// Result: same as above, more verbose, duplicates overridden
// Kotlin:
val map6 = persons.groupBy { it.age }.mapValues { it.value.joinToString(";") { it.name } }
println(map6)
// output: {18=Max, 23=Peter;Pamela, 12=David}
// Result: YAY!!
Solo necesitábamos unir los valores coincidentes para colapsar las listas y proporcionar un
transformador para joinToString para pasar de la instancia de Person al Person.name .
// Java (verbose):
Collector<Person, StringJoiner, String> personNameCollector =
Collector.of(
() -> new StringJoiner(" | "), // supplier
(j, p) -> j.add(p.name.toUpperCase()), // accumulator
(j1, j2) -> j1.merge(j2), // combiner
StringJoiner::toString); // finisher
// Java (concise)
String names = persons.stream().map(p -> p.name.toUpperCase()).collect(Collectors.joining(" |
"));
// Kotlin:
val names = persons.map { it.name.toUpperCase() }.joinToString(" | ")
https://riptutorial.com/es/home 39
Ejemplo de recopilación # 7b: recopilación con SummarizingInt
// Java:
IntSummaryStatistics ageSummary =
persons.stream()
.collect(Collectors.summarizingInt(p -> p.age));
System.out.println(ageSummary);
// IntSummaryStatistics{count=4, sum=76, min=12, average=19.000000, max=23}
// Kotlin:
println(stats)
// output: SummaryStatisticsInt(count=4, sum=76, min=12, max=23, avg=19.0)
Pero es mejor crear una función de extensión, 2 en realidad para que coincida con los estilos en
Kotlin stdlib:
// Kotlin:
inline fun Collection<Int>.summarizingInt(): SummaryStatisticsInt
= this.fold(SummaryStatisticsInt()) { stats, num -> stats.accumulate(num) }
// or
Y todos estos producen los mismos resultados. También podemos crear esta extensión para
trabajar en Sequence y para tipos primitivos apropiados.
https://riptutorial.com/es/home 40
Lea Equivalentes de flujo de Java 8 en línea:
https://riptutorial.com/es/kotlin/topic/707/equivalentes-de-flujo-de-java-8
https://riptutorial.com/es/home 41
Capítulo 14: Excepciones
Examples
Cogiendo la excepción con try-catch-finally
try {
doSomething()
}
catch(e: MyException) {
handle(e)
}
finally {
cleanup()
}
try {
doSomething()
}
catch(e: FileSystemException) {
handle(e)
}
catch(e: NetworkException) {
handle(e)
}
catch(e: MemoryException) {
handle(e)
}
finally {
cleanup()
}
Kotlin no ha comprobado las excepciones, por lo que no tiene que detectar ninguna excepción.
https://riptutorial.com/es/home 42
Capítulo 15: Extensiones Kotlin para Android
Introducción
Kotlin tiene una inyección de vista incorporada para Android, que permite omitir el enlace manual
o la necesidad de marcos como ButterKnife. Algunas de las ventajas son una mejor sintaxis, una
mejor escritura estática y, por lo tanto, son menos propensos a errores.
Examples
Configuración
buildscript {
...
}
Usando vistas
Suponiendo que tenemos una actividad con un diseño de ejemplo llamado activity_main.xml :
<Button
android:id="@+id/my_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="My button"/>
</LinearLayout>
Podemos usar las extensiones de Kotlin para llamar al botón sin ningún enlace adicional como:
import kotlinx.android.synthetic.main.activity_main.my_button
https://riptutorial.com/es/home 43
setContentView(R.layout.activity_main)
// my_button is already casted to a proper type of "Button"
// instead of being a "View"
my_button.setText("Kotlin rocks!")
}
}
También puede importar todos los identificadores que aparecen en el diseño con una notación *
Las vistas sintéticas no se pueden usar fuera de Actividades / Fragmentos / Vistas con ese diseño
inflado:
import kotlinx.android.synthetic.main.activity_main.my_button
class NotAView {
init {
// This sample won't compile!
my_button.setText("Kotlin rocks!")
}
}
Las extensiones de Android también funcionan con múltiples sabores de productos de Android.
Por ejemplo, si tenemos sabores en build.gradle así:
android {
productFlavors {
paid {
...
}
free {
...
}
}
}
<Button
android:id="@+id/buy_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Buy full version"/>
</LinearLayout>
https://riptutorial.com/es/home 44
Podemos unir específicamente al sabor:
import kotlinx.android.synthetic.free.main_activity.buy_button
mView.afterMeasured {
// inside this block the view is completely drawn
// you can get view's height/width, it.height / it.width
}
Bajo el capó
https://riptutorial.com/es/home 45
Capítulo 16: Funciones
Sintaxis
• Nombre divertido ( Params ) = ...
• Nombre divertido ( Params ) {...}
• Nombre divertido ( Params ): Tipo {...}
• fun < Type Argument > Name ( Params ): Type {...}
• Nombre de diversión en línea ( Parámetros ): Escriba {...}
• { ArgName : ArgType -> ...}
• { ArgName -> ...}
• { ArgNames -> ...}
• {( ArgName : ArgType ): Type -> ...}
Parámetros
Parámetro Detalles
Examples
Funciones que toman otras funciones
Como se ve en "Funciones Lambda", las funciones pueden tomar otras funciones como un
parámetro. El "tipo de función" que deberá declarar funciones que aceptan otras funciones es el
siguiente:
https://riptutorial.com/es/home 46
(arg1: String, arg2: Int) -> ReturnType
Por ejemplo, podría usar el tipo más vago, () -> Any? , para declarar una función que ejecuta una
función lambda dos veces:
fun main() {
twice {
println("Foo")
} # => Foo
# => Foo
}
Funciones Lambda
Las funciones Lambda son funciones anónimas que generalmente se crean durante una llamada
de función para actuar como un parámetro de función. Se declaran mediante expresiones
circundantes con {llaves}: si se necesitan argumentos, estos se colocan antes de una flecha -> .
Los tipos son opcionales, si coloca la lambda en un lugar donde el compilador puede inferir los
tipos.
Múltiples argumentos:
Si el único argumento de una función es una función lambda, los paréntesis se pueden omitir
completamente de la llamada a la función.
https://riptutorial.com/es/home 47
Referencias de funciones
Podemos hacer referencia a una función sin realmente llamarla prefijando el nombre de la función
con :: . Esto se puede pasar a una función que acepta alguna otra función como parámetro.
Las funciones sin receptor se convertirán a (ParamTypeA, ParamTypeB, ...) -> ReturnType donde
ParamTypeA , ParamTypeB ... son el tipo de parámetros de la función y `ReturnType1 es el tipo de
valor de retorno de la función.
Las funciones con un receptor (ya sea una función de extensión o una función miembro) tienen
una sintaxis diferente. Debe agregar el nombre de tipo del receptor antes de los dos puntos
dobles:
class Foo
fun Foo.foo(p0: Foo0, p1: Foo1, p2: Foo2): Bar {
//...
}
val ref = Foo::foo
println(ref::class.java.genericInterfaces[0])
// kotlin.jvm.functions.Function4<Foo, Foo0, Foo1, Foo2, Bar>
// Human readable type: (Foo, Foo0, Foo1, Foo2) -> Bar
// takes 4 parameters, with receiver as first and actual parameters following, in their order
class Bar {
fun bar()
}
print(Bar::bar) // works on member functions, too.
Sin embargo, cuando el receptor de una función es un objeto, el receptor se omite de la lista de
parámetros, porque este es y solo es una instancia de ese tipo.
object Foo
fun Foo.foo(p0: Foo0, p1: Foo1, p2: Foo2): Bar {
//...
}
val ref = Foo::foo
println(ref::class.java.genericInterfaces[0])
// kotlin.jvm.functions.Function3<Foo0, Foo1, Foo2, Bar>
// Human readable type: (Foo0, Foo1, Foo2) -> Bar
// takes 3 parameters, receiver not needed
https://riptutorial.com/es/home 48
object Bar {
fun bar()
}
print(Bar::bar) // works on member functions, too.
Desde kotlin 1.1, la referencia de función también puede estar limitada a una variable, que luego
se denomina referencia de función limitada .
1.1.0
Tenga en cuenta que este ejemplo se proporciona solo para mostrar cómo funciona la referencia de función acotada.
Es una mala práctica en todos los demás sentidos.
Sin embargo, hay un caso especial. Una función de extensión declarada como miembro no puede
ser referenciada.
class Foo
class Bar {
fun Foo.foo() {}
val ref = Foo::foo // compile error
}
Funciones básicas
Las funciones se declaran utilizando la palabra clave fun , seguida de un nombre de función y
cualquier parámetro. También puede especificar el tipo de retorno de una función, que por defecto
es Unit . El cuerpo de la función está encerrado entre llaves {} . Si el tipo de devolución es distinto
de Unit , el cuerpo debe emitir una declaración de devolución para cada rama de terminación
dentro del cuerpo.
Funciones abreviadas
https://riptutorial.com/es/home 49
Si una función contiene solo una expresión, podemos omitir los corchetes y usar un igual en su
lugar, como una asignación de variable. El resultado de la expresión se devuelve
automáticamente.
Funciones en línea
Las funciones se pueden declarar en línea usando el prefijo en inline , y en este caso actúan
como macros en C, en lugar de ser llamadas, se reemplazan por el código del cuerpo de la
función en el momento de la compilación. Esto puede llevar a beneficios de rendimiento en
algunas circunstancias, principalmente cuando las lambdas se utilizan como parámetros de
función.
Una diferencia de las macros de C es que las funciones en línea no pueden acceder al ámbito
desde el que se llaman:
fun main() {
val name = "Foo"
sayMyName() # => Unresolved reference: name
}
https://riptutorial.com/es/home 50
Capítulo 17: Fundamentos de Kotlin
Introducción
Este tema cubre los conceptos básicos de Kotlin para principiantes.
Observaciones
1. El archivo Kotlin tiene una extensión .kt.
2. Todas las clases en Kotlin tienen una superclase común Cualquiera, que es un super
predeterminado para una clase sin supertipos declarados (similar a Objeto en Java).
3. Las variables se pueden declarar como val (inmutable-asignar una vez) o var (el valor de
mutables se puede cambiar)
4. No se necesita punto y coma al final de la declaración.
5. Si una función no devuelve ningún valor útil, su tipo de retorno es Unidad. También es
opcional. 6.La igualdad de referencia se verifica mediante la operación ===. a === b se
evalúa como verdadero si y solo si a y b apuntan al mismo objeto.
Examples
Ejemplos basicos
1.La declaración de tipo de retorno de la unidad es opcional para las funciones. Los siguientes
códigos son equivalentes.
2. Funciones de expresión simple: cuando una función devuelve una expresión única, se pueden
omitir las llaves y el cuerpo se especifica después de = symbol
https://riptutorial.com/es/home 51
In java:
int num=10
String s = "i =" + i;
In Kotlin
val num = 10
val s = "i = $num"
4. En Kotlin, el sistema de tipos distingue entre las referencias que pueden contener nulas
(referencias que admiten nulos) y las que no (referencias no nulas). Por ejemplo, una variable
regular de tipo String no puede contener null:
Para permitir valores nulos, podemos declarar una variable como cadena anulable, ¿cadena
escrita ?:
5.En Kotlin, == realmente verifica la igualdad de valores. Por convención, una expresión como a
== b se traduce a
https://riptutorial.com/es/home 52
Capítulo 18: Gamas
Introducción
Las expresiones de rango se forman con funciones rangeTo que tienen la forma de operador ..
que se complementa con in y! In. El rango se define para cualquier tipo comparable, pero para los
tipos primitivos integrales tiene una implementación optimizada
Examples
Tipos de rangos integrales
Los rangos de tipos integrales (IntRange, LongRange, CharRange) tienen una característica
adicional: pueden ser iterados. El compilador se encarga de convertir esto de manera análoga al
bucle for-indexado de Java, sin sobrecarga adicional
función downTo ()
¿Si quieres iterar sobre números en orden inverso? Es sencillo. Puede usar la función downTo ()
definida en la biblioteca estándar
función de paso
¿Es posible iterar sobre números con un paso arbitrario, no igual a 1? Claro, la función step () te
ayudará.
hasta la función
Para crear un rango que no incluya su elemento final, puede usar la función until:
https://riptutorial.com/es/home 53
Capítulo 19: Genéricos
Introducción
Una lista puede contener números, palabras o realmente cualquier cosa. Por eso llamamos a la
lista genérica .
Los genéricos se usan básicamente para definir qué tipos puede contener una clase y qué tipo
tiene un objeto actualmente.
Sintaxis
• clase ClassName < TypeName >
• clase ClassName <*>
• ClassName <en UpperBound >
• ClassName <out LowerBound >
• Nombre de la clase < TypeName : UpperBound >
Parámetros
Parámetro Detalles
Observaciones
class Consumer<T>
https://riptutorial.com/es/home 54
class Consumer<T: Any>
Examples
Variación del sitio de la declaración
La variación del sitio de la declaración se puede considerar como una declaración de la variación
del sitio de uso de una vez por todas.
Los ejemplos generalizados de varianza del sitio de declaración son List<out T> , que es
inmutable, de modo que T solo aparece como el tipo de valor de retorno, y Comparator<in T> , que
solo recibe T como argumento.
Out-proyección:
En proyección:
putList[0] // This expression has type Any, since no upper bound is specified
Proyección de estrellas
starList[0] // This expression has type Any, since no upper bound is specified
starList.add(someValue) // Error, lower bound for generic is not specified
Ver también:
https://riptutorial.com/es/home 55
• Variante de interoperabilidad de genéricos al llamar a Kotlin desde Java.
https://riptutorial.com/es/home 56
Capítulo 20: Herencia de clase
Introducción
Cualquier lenguaje de programación orientado a objetos tiene alguna forma de herencia de clase.
Déjame revisar:
Imagina que tienes que programar un montón de frutas: Apples , Oranges y Pears . Todos ellos
difieren en tamaño, forma y color, por eso tenemos diferentes clases.
Pero digamos que sus diferencias no importan por un segundo y usted solo quiere una Fruit , ¿no
importa cuál exactamente? ¿Qué tipo de retorno tendría getFruit() ?
La respuesta es clase Fruit . ¡Creamos una nueva clase y hacemos que todas las frutas hereden
de ella!
Sintaxis
• abrir {clase base}
• class {Clase derivada}: {Clase base} ({Init Arguments})
• anular {definición de función}
• {DC-Object} es {Clase base} == verdadero
Parámetros
Parámetro Detalles
Examples
Conceptos básicos: la palabra clave 'abrir'
En Kotlin, las clases son finales por defecto, lo que significa que no se pueden heredar de.
https://riptutorial.com/es/home 57
Para permitir la herencia en una clase, use la palabra clave open .
Nota: las clases abstractas, las clases selladas y las interfaces estarán open de forma
predeterminada.
Usando la subclase:
https://riptutorial.com/es/home 58
El Ninja tiene acceso a todos los métodos en persona
Métodos de anulación:
interface Ship {
fun sail()
fun sink()
}
https://riptutorial.com/es/home 59
Capítulo 21: Instrumentos de cuerda
Examples
Elementos de cuerda
Los elementos de cadena son caracteres a los que se puede acceder mediante la string[index]
operación de indexación string[index] .
for (c in str) {
println(c)
}
Literales de cuerda
• Cuerda escapada
• Cuerda cruda
Cadena escapada maneja caracteres especiales al escapar de ellos. El escape se hace con una
barra invertida. Se admiten las siguientes secuencias de escape: \t , \b , \n , \r , \' , \" , \\ y \$ .
Para codificar cualquier otro carácter, use la sintaxis de secuencia de escape de Unicode: \uFF00 .
La cadena sin formato delimitada por una comilla triple """ no contiene escapes y puede
contener nuevas líneas y cualquier otro carácter
https://riptutorial.com/es/home 60
El prefijo de margen predeterminado es carácter de canalización | , esto se puede establecer
como un parámetro para trimMargin; por ejemplo, trimMargin(">") .
Plantillas de cadena
Tanto las cadenas de escape como las cadenas sin formato pueden contener expresiones de
plantilla. La expresión de plantilla es un fragmento de código que se evalúa y su resultado se
concatena en una cadena. Comienza con un signo de dólar $ y consta de un nombre variable:
val i = 10
val s = "i = $i" // evaluates to "i = 10"
val s = "abc"
val str = "$s.length is ${s.length}" // evaluates to "abc.length is 3"
Para incluir un signo de dólar literal en una cadena, escápelo con una barra invertida:
La excepción son las cadenas sin formato, que no admiten el escape. En cadenas sin formato,
puede utilizar la siguiente sintaxis para representar un signo de dólar.
Igualdad de cuerdas
En Kotlin, las cuerdas se comparan con el operador == que las selecciona para su igualdad
estructural.
https://riptutorial.com/es/home 61
println(str1 === str2) // Prints false
println(str1 === str3) // Prints true
https://riptutorial.com/es/home 62
Capítulo 22: Interfaces
Observaciones
Consulte también: Documentación de referencia de Kotlin para interfaces: Interfaces
Examples
Interfaz básica
interface MyInterface {
fun bar()
}
Esta interfaz ahora puede ser implementada por una clase de la siguiente manera:
interface MyInterface {
fun withImplementation() {
print("withImplementation() was called")
}
}
Las clases que implementen dichas interfaces podrán usar esas funciones sin volver a
implementarlas.
Propiedades
Las implementaciones predeterminadas también funcionan para los que obtienen y establecen
https://riptutorial.com/es/home 63
propiedades:
interface MyInterface2 {
val helloWorld
get() = "Hello World!"
}
interface MyInterface3 {
// this property won't compile!
var helloWorld: Int
get() = field
set(value) { field = value }
}
Implementaciones multiples
Cuando varias interfaces implementan la misma función, o todas ellas se definen con una o más
implementaciones, la clase derivada debe resolver manualmente la llamada apropiada
interface A {
fun notImplemented()
fun implementedOnlyInA() { print("only A") }
fun implementedInBoth() { print("both, A") }
fun implementedInOne() { print("implemented in A") }
}
interface B {
fun implementedInBoth() { print("both, B") }
fun implementedInOne() // only defined
}
class MyClass: A, B {
override fun notImplemented() { print("Normal implementation") }
Propiedades en interfaces
Puedes declarar propiedades en interfaces. Dado que una interfaz no puede tener un estado, solo
https://riptutorial.com/es/home 64
puede declarar una propiedad como abstracta o proporcionando una implementación
predeterminada para los usuarios.
interface MyInterface {
val property: Int // abstract
fun foo() {
print(property)
}
}
Cuando se implementa más de una interfaz que tiene métodos del mismo nombre que incluyen
implementaciones predeterminadas, es ambiguo para el compilador qué implementación se debe
usar. En el caso de un conflicto, el desarrollador debe anular el método conflictivo y proporcionar
una implementación personalizada. Esa implementación puede optar por delegar a las
implementaciones por defecto o no.
interface FirstTrait {
fun foo() { print("first") }
fun bar()
}
interface SecondTrait {
fun foo() { print("second") }
fun bar() { print("bar") }
}
// function bar() only has a default implementation in one interface and therefore is ok.
}
interface MyInterface {
fun funcOne() {
//optional body
print("Function with default implementation")
}
}
https://riptutorial.com/es/home 65
Si el método en la interfaz tiene su propia implementación predeterminada, podemos usar la
palabra clave super para acceder a él.
super.funcOne()
https://riptutorial.com/es/home 66
Capítulo 23: JUIT
Examples
Reglas
La anotación @JvmField es necesaria para exponer el campo de respaldo con la misma visibilidad
(pública) que la propiedad myRule (ver respuesta ). Las reglas de JUnit requieren que el campo de
la regla anotada sea público.
https://riptutorial.com/es/home 67
Capítulo 24: Kotlin para desarrolladores de
Java
Introducción
La mayoría de las personas que vienen a Kotlin tienen un fondo de programación en Java.
Este tema recopila ejemplos que comparan Java con Kotlin, resaltando las diferencias más
importantes y las gemas que Kotlin ofrece sobre Java.
Examples
Declarando variables
val i : Int = 42
• Comienzan con cualquiera val o var , hacer la declaración final ( "ue val") o iable var.
Java Kotlin
Hechos rápidos
https://riptutorial.com/es/home 68
• Kotlin soporta sobrecargas de operadores (limitadas). Por ejemplo, el acceso a un valor
de un mapa puede escribirse como: val a = someMap["key"]
• Kotlin no solo se puede compilar en un código de bytes para la JVM, sino también en Java
Script , lo que le permite escribir tanto el código de backend como el de frontend en Kotlin
• Kotlin es totalmente compatible con Java 6 , lo cual es especialmente interesante en lo
que respecta al soporte de dispositivos Android (no tan antiguos)
• Kotlin es un lenguaje soportado oficialmente para el desarrollo de Android
• Las colecciones de Kotlin tienen una distinción integrada entre las colecciones mutables e
inmutables .
• Kotlin apoya a los coroutines (experimental)
Igualdad e identidad
Kotlin usa == para la igualdad (es decir, las llamadas son equals internamente) y === para la
identidad referencial.
Java Kotlin
a.equals(b); a == b
a == b; a === b
a != b; a !== b
Consulte: https://kotlinlang.org/docs/reference/equality.html
En Kotlin, if , try y otros son expresiones (por lo que devuelven un valor) en lugar de
declaraciones (nulas).
Entonces, por ejemplo, Kotlin no tiene el operador Elvis ternario de Java, pero puede escribir algo
como esto:
val i = try {
Integer.parseInt(someString)
}
catch (ex : Exception)
{
42
}
https://riptutorial.com/es/home 69
Capítulo 25: Lambdas basicas
Sintaxis
• Parámetros explícitos:
• Parámetros inferidos:
• Firma:
• () -> ResultType
Observaciones
Los parámetros de tipo de entrada se pueden omitir cuando se pueden omitir cuando se pueden
inferir del contexto. Por ejemplo, digamos que tiene una función en una clase que toma una
función:
Puede utilizar esta función pasando un lambda, y como los parámetros ya están especificados en
la firma de la función, no es necesario volver a declararlos en la expresión lambda:
//valid:
val addition: (Int, Int) = { a, b -> a + b }
https://riptutorial.com/es/home 70
//valid:
val addition = { a: Int, b: Int -> a + b }
//error (type inference failure):
val addition = { a, b -> a + b }
Cuando la lambda toma un parámetro, y el tipo se puede inferir del contexto, puede referirse al
parámetro por it .
listOf(1,2,3).map { it * 2 } // [2,4,6]
Examples
Lambda como parámetro para filtrar la función.
Cronómetro de propósito general para medir el tiempo que tarda una función en ejecutarse:
object Benchmark {
fun realtime(body: () -> Unit): Duration {
val start = Instant.now()
try {
body()
} finally {
val end = Instant.now()
return Duration.between(start, end)
}
}
}
Uso:
https://riptutorial.com/es/home 71
Capítulo 26: loguearse en kotlin
Observaciones
Pregunta relacionada: Forma idiomática de registro en Kotlin
Examples
kotlin.logging
class FooWithLogging {
companion object: KLogging()
fun bar() {
logger.info { "hello $name" }
}
https://riptutorial.com/es/home 72
Capítulo 27: Métodos de extensión
Sintaxis
• fun TypeName.extensionName (params, ...) {/ * body * /} // Declaración
• fun <T: Any> TypeNameWithGenerics <T> .extensionName (params, ...) {/ * body * /} //
Declaración con genéricos
• myObj.extensionName (args, ...) // invocación
Observaciones
Las extensiones se resuelven estáticamente . Esto significa que el método de extensión que se
utilizará está determinado por el tipo de referencia de la variable a la que está accediendo; No
importa cuál sea el tipo de la variable en el tiempo de ejecución, siempre se llamará al mismo
método de extensión. Esto se debe a que declarar un método de extensión en realidad no
agrega un miembro al tipo de receptor .
Examples
Extensiones de nivel superior
Los métodos de extensión de nivel superior no están contenidos dentro de una clase.
Encima se define un método de extensión para el tipo IntArray . Tenga en cuenta que se accede
al objeto para el que se define el método de extensión (llamado receptor ) con la palabra clave
this .
https://riptutorial.com/es/home 73
class Sub : Super()
callMyExtension(Sub())
El ejemplo anterior imprimirá "Defined for Super" , porque el tipo declarado de la variable myVar es
Super .
Muestra que se extiende por mucho tiempo para representar una cadena
humana legible
Dado cualquier valor de tipo Int o Long para representar una cadena legible por humanos:
println(1999549L.humanReadable())
println(someInt.humanReadable())
Un caso de uso común para los métodos de extensión es mejorar una API existente. Aquí hay
ejemplos de notExists agregar exist , notExists y deleteRecursively a la clase Java 7+ Path :
https://riptutorial.com/es/home 74
Usando funciones de extensión para mejorar la legibilidad
Pero el uso de apply no es tan claro en cuanto a su intención. A veces es más claro crear una
función de extensión similar para, en efecto, cambiar el nombre de la acción y hacerla más
evidente. No se debe permitir que esto se salga de control, pero para acciones muy comunes
como la verificación:
Que ahora la gente sepa qué esperar dentro del parámetro lambda.
Tenga en cuenta que el parámetro de tipo T para verifiedBy es el mismo que T: Any? lo que
significa que incluso los tipos anulables podrán usar esa versión de la extensión. Aunque
verifiedWith requiere no anulable.
https://riptutorial.com/es/home 75
estáticas)
Si desea extender una clase como-si es una función estática, por ejemplo, para la clase Something
agregue la función de aspecto estático desde la fromString , esto solo puede funcionar si la clase
tiene un objeto complementario y la función de extensión se ha declarado en el objeto
complementario. :
class Something {
companion object {}
}
class SomethingElse {
}
SomethingElse.fromString("") //invalid
}
Supongamos que desea crear una propiedad de extensión que sea costosa de computar. Así que
le gustaría almacenar en caché el cálculo, utilizando el delegado propiedad perezosa y se refieren
a instancia actual ( this ), pero no puede hacerlo, como se explica en el Kotlin emite KT-9686 y
KT-13053 . Sin embargo, hay una solución oficial proporcionada aquí .
Puede usar extensiones para la vista de referencia, no más repeticiones después de crear las
vistas.
https://riptutorial.com/es/home 76
Extensiones
Uso
https://riptutorial.com/es/home 77
Capítulo 28: Modificadores de visibilidad
Introducción
En Kotlin, hay 4 tipos de modificadores de visibilidad disponibles.
Protegido: solo se puede acceder a él desde la clase que lo define y desde cualquier clase
derivada.
Sintaxis
• <visibility modifier> val/var <variable name> = <value>
Examples
Ejemplo de código
https://riptutorial.com/es/home 78
Capítulo 29: Modismos
Examples
Creación de DTO (POJOs / POCOs)
Las clases de datos en kotlin son clases creadas para hacer nada más que mantener datos. Tales
clases están marcadas como data :
data class User(var firstname: String, var lastname: String, var age: Int)
El código anterior crea una clase de User con lo siguiente generado automáticamente:
• Getters y Setters para todas las propiedades (getters solo para val s)
• equals()
• hashcode()
• toString()
• copy()
• componentN() (donde N es la propiedad correspondiente en orden de declaración)
Al igual que con una función, los valores predeterminados también se pueden especificar:
data class User(var firstname: String = "Joe", var lastname: String = "Bloggs", var age: Int =
20)
Suponga que desea delegar en una clase pero no desea proporcionar la clase delegada a en el
parámetro constructor. En su lugar, desea construirlo de forma privada, haciendo que el
constructor que llama no lo sepa. Al principio, esto puede parecer imposible porque la delegación
de clase permite delegar solo a los parámetros del constructor. Sin embargo, hay una manera de
hacerlo, como se indica en esta respuesta :
class MyTable private constructor(table: Table<Int, Int, Int>) : Table<Int, Int, Int> by table
{
https://riptutorial.com/es/home 79
constructor() : this(TreeBasedTable.create()) // or a different type of table if desired
Con esto, puedes llamar al constructor de MyTable así: MyTable() . La Table<Int, Int, Int> en la
que se crearán los delegados de MyTable forma privada. El que llama al constructor no sabe nada
al respecto.
Para crear el serialVersionUID para una clase en Kotlin, tiene algunas opciones, todas
relacionadas con la adición de un miembro al objeto complementario de la clase.
El bytecode más conciso proviene de una private const val que se convertirá en una variable
estática privada en la clase contenedora, en este caso MySpecialCase :
También puede usar estos formularios, cada uno con el efecto secundario de tener métodos
de obtención / establecimiento que no son necesarios para la serialización ...
Esto crea el campo estático, pero también crea un getter y getSerialVersionUID en el objeto
complementario que no es necesario.
Esto crea el campo estático, pero también crea un getter estático y getSerialVersionUID en la clase
que contiene MySpecialCase que no es necesario.
Pero todo funciona como un método para agregar el serialVersionUID a una clase Serializable .
Los métodos fluidos en Kotlin pueden ser los mismos que en Java:
https://riptutorial.com/es/home 80
fun doSomething() {
someOtherAction()
return this
}
Pero también puede hacer que sean más funcionales creando una función de extensión como:
fun doSomething() {
return fluently { someOtherAction() }
}
let Kotlin cree un enlace local desde el objeto al que fue llamado. Ejemplo:
La diferencia entre let y also es que puede devolver cualquier valor de un bloque let . also en la
otra parte siempre reutrn la Unit .
Ahora, ¿por qué esto es útil, preguntas? Porque si llama a un método que puede devolver null y
desea ejecutar algún código solo cuando el valor de retorno no es null , puede usar let o also
esto:
Este fragmento de código solo ejecutará el bloque let cuando str no sea null . Tenga en cuenta
el operador de seguridad null ( ? ).
llama al bloque de funciones especificado con this valor como su receptor y devuelve
https://riptutorial.com/es/home 81
this valor.
Mientras que el kdoc no es tan útil apply es de hecho una función útil. En términos sencillos, apply
establece un alcance en el que this está vinculado al objeto al que llamó apply . Esto le permite
ahorrar algo de código cuando necesita llamar a múltiples métodos en un objeto que luego
devolverá. Ejemplo:
File(dir).apply { mkdirs() }
https://riptutorial.com/es/home 82
Capítulo 30: Objetos singleton
Introducción
Un objeto es un tipo especial de clase, que se puede declarar utilizando la palabra clave object .
Los objetos son similares a Singletons (un patrón de diseño) en Java. También funciona como la
parte estática de java. Los principiantes que cambian de java a kotlin pueden usar ampliamente
esta función, en lugar de estática o singletons.
Examples
Utilizar como repalcement de métodos estáticos / campos de java
object CommonUtils {
Desde cualquier otra clase, simplemente invoca la variable y las funciones de esta manera:
CommonUtils.anyname
CommonUtils.dispMsg("like static call")
Los objetos de Kotlin son en realidad solo singletons. Su principal ventaja es que no tiene que
usar SomeSingleton.INSTANCE para obtener la instancia del singleton.
https://riptutorial.com/es/home 83
object SharedRegistry {
fun register(key: String, thing: Object) {}
}
https://riptutorial.com/es/home 84
Capítulo 31: Parámetros Vararg en Funciones
Sintaxis
• Palabra clave Vararg : vararg se utiliza en una declaración de método para indicar que se
aceptará un número variable de parámetros.
• Operador de propagación : un asterisco ( * ) antes de una matriz que se utiliza en
llamadas a funciones para "desplegar" los contenidos en parámetros individuales.
Examples
Conceptos básicos: Uso de la palabra clave vararg
Ahora puede pasar tantos parámetros (del tipo correcto) a la función como desee.
https://riptutorial.com/es/home 85
El operador de propagación también se puede utilizar en medio de los parámetros ...
https://riptutorial.com/es/home 86
Capítulo 32: Propiedades delegadas
Introducción
Kotlin puede delegar la implementación de una propiedad a un objeto controlador. Se incluyen
algunos manejadores estándar, como la inicialización perezosa o propiedades observables.
También se pueden crear controladores personalizados.
Examples
Inicialización perezosa
El ejemplo imprime 2 .
Propiedades observables
El ejemplo imprime 1
Delegación personalizada
class MyDelegate {
operator fun getValue(owner: Any?, property: KProperty<*>): String {
return "Delegated value"
}
}
https://riptutorial.com/es/home 87
Delegado Se puede usar como una capa para reducir la placa de caldera
Entonces, digamos que tenemos que guardar algún tipo de referencia y queríamos evitar las
fugas de memoria, aquí es donde entra en WeakReference .
class MyMemoryExpensiveClass {
companion object {
var reference: WeakReference<MyMemoryExpensiveClass>? = null
init {
reference = WeakReference(this)
}
}
Ahora esto es solo con una WeakReference. Para reducir esta repetición, podemos usar un
delegado de propiedades personalizado para ayudarnos así:
¡Así que ahora podemos usar variables que están envueltas con WeakReference al igual que las
variables normales que WeakReference !
class MyMemoryExpensiveClass {
companion object {
var reference: MyMemoryExpensiveClass? by
WeakReferenceDelegate<MyMemoryExpensiveClass>()
init {
reference = this
}
https://riptutorial.com/es/home 88
}
https://riptutorial.com/es/home 89
Capítulo 33: RecyclerView en Kotlin
Introducción
Solo quiero compartir mi pequeño conocimiento y código de RecyclerView utilizando Kotlin.
Examples
Clase principal y adaptador
Supongo que tiene conocimiento de la sintaxis de Kotlin y de cómo usarla, simplemente agregue
RecyclerView en el archivo activity_main.xml y establezca con la clase de adaptador.
mRecyclerView.setHasFixedSize(true)
mRecyclerView.layoutManager = LinearLayoutManager(this)
mAdapter.RecyclerAdapter(getList(), this)
mRecyclerView.adapter = mAdapter
}
este es su clase de adaptador de vista de reciclador y cree el archivo main_item.xml que desee
https://riptutorial.com/es/home 90
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = mItems[position]
holder.bind(item, mClick, position)
}
https://riptutorial.com/es/home 91
Capítulo 34: Reflexión
Introducción
Reflexión es la capacidad de un lenguaje para inspeccionar el código en tiempo de ejecución en
lugar de compilarlo.
Observaciones
La reflexión es un mecanismo para realizar introspecciones de construcciones de lenguaje (clases
y funciones) en el tiempo de ejecución.
Examples
Hacer referencia a una clase
Para obtener una referencia a un objeto KClass que representa alguna clase, use dos puntos
dobles:
val c1 = String::class
val c2 = MyClass::class
Las funciones son ciudadanos de primera clase en Kotlin. Puede obtener una referencia en él
usando dos puntos dobles y luego pasarlo a otra función:
Para obtener un objeto Class de Java de KClass de Kotlin, use la propiedad de extensión .java :
https://riptutorial.com/es/home 92
El compilador optimizará este último ejemplo para no asignar una instancia de KClass intermedia.
Ejecutar este código hará que se genere una excepción. La propiedad private val privateField se
declara privada y llamar a member.get(example) no se realizará correctamente. Una forma de
manejarlo es filtrar propiedades privadas. Para hacer eso, tenemos que verificar el modificador de
visibilidad del Java getter de una propiedad. En el caso de private val el captador no existe, por
lo que podemos asumir el acceso privado.
Otro enfoque es hacer que las propiedades privadas sean accesibles mediante la reflexión:
https://riptutorial.com/es/home 93
Como ejemplo, queremos establecer todas las propiedades de cadena de una clase de muestra
class TestClass {
val readOnlyProperty: String
get() = "Read only!"
Obtener propiedades mutables se basa en obtener todas las propiedades, filtrando las
propiedades mutables por tipo. También necesitamos verificar la visibilidad, ya que la lectura de
propiedades privadas resulta en una excepción de tiempo de ejecución.
Para establecer todas las propiedades de String en "Our Value" , también podemos filtrar por el
tipo de retorno. Dado que Kotlin se basa en Java VM, Type Erasure está en vigencia y, por lo
tanto, las Propiedades que devuelven tipos genéricos como List<String> serán las mismas que
List<Any> . Lamentablemente, la reflexión no es una bala de oro y no hay una forma sensata de
evitar esto, por lo que debe tener cuidado en sus casos de uso.
https://riptutorial.com/es/home 94
.filter{ it.returnType.isSubtypeOf(String::class.starProjectedType) }
.filterIsInstance<KMutableProperty<*>>()
.forEach { prop ->
// Instead of printing the property we set it to some value
prop.setter.call(instance, "Our Value")
}
https://riptutorial.com/es/home 95
Capítulo 35: Regex
Examples
Modismos para la concordancia de expresiones regulares en cuando la
expresión
import kotlin.text.regex
when {
regex1.matches(string) -> /* do stuff */
regex2.matches(string) -> /* do stuff */
/* etc */
}
import kotlin.text.regex
when {
Regex( /* pattern */ ).matches(string) -> /* do stuff */
Regex( /* pattern */ ).matches(string) -> /* do stuff */
/* etc */
}
https://riptutorial.com/es/home 96
ciertos errores de programación que podrían surgir al tener que repetir el argumento when en todos
los whenEntry . Ya sea la plantilla de "locales inmutables" o "temporarios anónimos" se puede usar
con esta implementación como patrón de visitante.
import kotlin.text.regex
when (RegexWhenArgument(string)) {
Regex( /* pattern */ ) -> /* do stuff */
Regex( /* pattern */ ) -> /* do stuff */
/* etc */
}
Esta publicación muestra cómo usar la mayoría de las funciones en la clase Regex , trabajar con
nulos relacionados con las funciones Regex y cómo las cadenas en bruto facilitan la escritura y
lectura de patrones de expresiones regulares.
La clase RegEx
Para trabajar con expresiones regulares en Kotlin, debe usar la Regex(pattern: String) e invocar
funciones como find(..) o replace(..) en ese objeto de expresión regular.
Un ejemplo sobre cómo usar la clase Regex que devuelve verdadero si la cadena de input contiene
c o d:
Lo esencial a entender con todas las funciones Regex es que el resultado se basa en hacer
coincidir el pattern regex y la cadena de input . Algunas de las funciones requieren una
coincidencia completa, mientras que el resto solo requiere una coincidencia parcial. La función
containsMatchIn(..) utilizada en el ejemplo requiere una coincidencia parcial y se explica más
adelante en esta publicación.
https://riptutorial.com/es/home 97
de MatchResult es necesario para que Kotlin maneje el nulo de forma segura .
Un ejemplo que demuestra cómo Kotlin maneja nulo de forma segura desde una función Regex ,
cuando la función find(..) devuelve null:
val matchResult =
Regex("c|d").find("efg") // matchResult: null
val a = matchResult?.value // a: null
val b = matchResult?.value.orEmpty() // b: ""
a?.toUpperCase() // Still needs question mark. => null
b.toUpperCase() // Accesses the function directly. => ""
Con la función orEmpty() , b no puede ser nulo y el ? el carácter no es necesario cuando llamas
funciones en b .
Si no se preocupan por esta manipulación segura de los valores nulos, Kotlin le permite trabajar
con valores nulos como en Java con el !! caracteres:
Para extraer el primer número de teléfono válido de una cadena con detalles de contacto:
Sin un número de teléfono válido en la cadena de input , la variable phoneNumber será null .
https://riptutorial.com/es/home 98
findAll (input: CharSequence, startIndex: Int):
secuencia
Devuelve todas las coincidencias de la cadena de input que coincide con el pattern expresiones
regulares.
Para imprimir todos los números separados por espacios, desde un texto con letras y dígitos:
println(result) // => 12 34
La variable matchedResults es una secuencia con objetos MatchResult . Con una cadena de input
sin dígitos, la función findAll(..) devolverá una secuencia vacía.
https://riptutorial.com/es/home 99
Boolean
Devuelve verdadero si parte de la cadena de entrada coincide con el patrón de expresiones
regulares. Falso de lo contrario.
Hay un elemento en la lista para cada división. La primera cadena de input tiene tres números.
Eso resulta en una lista con tres elementos.
https://riptutorial.com/es/home 100
Capítulo 36: Seguridad nula
Examples
Tipos anulables y no anulables
Los tipos normales, como String , no son anulables. Para que sean capaces de mantener valores
nulos, tiene que denotar explícitamente al poner un ? detrás de ellos: String?
Para acceder a las funciones y propiedades de los tipos anulables, debe utilizar operadores
especiales.
obj?.apply {
foo()
bar()
}
Esto llamará foo y bar en obj (que es this en el bloque de apply ) solo si obj no es nulo, omitiendo
todo el bloque de lo contrario.
Para poner una variable anulable dentro del alcance como una referencia no anulable sin
convertirla en el receptor implícito de llamadas de función y propiedad, puede usar let lugar de
apply :
https://riptutorial.com/es/home 101
notnull.foo()
notnull.bar()
}
notnull podría tener un nombre, o incluso notnull y usarse a través del parámetro lambda
implícito it .
Moldes inteligentes
Si el compilador puede inferir que un objeto no puede ser nulo en un cierto punto, ya no tiene que
usar los operadores especiales:
Si se puede acceder a una variable desde fuera del alcance del bloque actual (debido
a que son miembros de un objeto no local, por ejemplo), debe crear una referencia
local nueva que luego pueda realizar una conversión inteligente y usar.
A veces es deseable evaluar una expresión anulable de una manera si no es así. El operador de
elvis, ?: , Se puede usar en Kotlin para tal situación.
Por ejemplo:
La expresión anterior devuelve "Nothing here" si los data?.first() o los data sí mismos arrojan un
valor null o el resultado de los data?.first() .
También es posible lanzar excepciones utilizando la misma sintaxis para abortar la ejecución del
código.
https://riptutorial.com/es/home 102
val value: String = data?.second()
?: throw IllegalArgumentException("Value can't be null!")
Afirmación
!! los sufijos ignoran la nulabilidad y devuelven una versión no nula de ese tipo.
KotlinNullPointerException lanzará KotlinNullPointerException si el objeto es un null .
Operador Elvis (? :)
En Kotlin, podemos declarar una variable que puede contener una null reference . Supongamos
que tenemos una referencia anulable a , podemos decir "si a no es nulo, utilícelo; de lo contrario,
use un valor no nulo x "
Ahora, a puede ser nulo. Entonces, cuando necesitamos acceder al valor de a , debemos realizar
una verificación de seguridad, ya sea que contenga valor o no. Podemos realizar esta verificación
de seguridad por convencional if...else declaración.
Pero aquí viene el operador avanzado Elvis (operador Elvis ?: . Más arriba if...else puede
expresarse con el operador de Elvis de la siguiente manera:
val b = a?.length ?: -1
https://riptutorial.com/es/home 103
Capítulo 37: Tipo de alias
Introducción
Con los alias de tipo, podemos dar un alias a otro tipo. Es ideal para dar un nombre a tipos de
funciones como (String) -> Boolean Tipo (String) -> Boolean o genérico como Pair<Person,
Person> .
Los alias de tipo soportan genéricos. Un alias puede reemplazar un tipo con genéricos y un alias
puede ser genéricos.
Sintaxis
• typealias nombre-alias = tipo-existente
Observaciones
Los alias de tipo son una característica del compilador. No se agrega nada en el código generado
para la JVM. Todos los alias serán reemplazados por el tipo real.
Examples
Tipo de función
Tipo genérico
https://riptutorial.com/es/home 104
Capítulo 38: Tipo de constructores seguros
Observaciones
Un generador de tipos seguros es un concepto, en lugar de una característica de lenguaje, por lo
que no está estrictamente formalizado.
1. Crea un objeto.
2. Ejecuta lambda para inicializar el objeto.
3. Agregue el objeto a estructurar o devuélvalo.
• Anko
• Wasabi
• Ktor
• Especulación
Examples
Generador de estructura de árbol de tipo seguro
Los constructores se pueden definir como un conjunto de funciones de extensión que toman
expresiones lambda con receptores como argumentos. En este ejemplo, se está construyendo un
menú de un JFrame :
import javax.swing.*
https://riptutorial.com/es/home 105
fun JMenu.menuItem(caption: String, init: JMenuItem.() -> Unit) {
val menuItem = JMenuItem(caption)
menuItem.init()
add(menuItem)
}
Estas funciones se pueden usar para construir una estructura de árbol de objetos de una manera
fácil:
https://riptutorial.com/es/home 106
Creditos
S.
Capítulos Contributors
No
Advertencias de
2 Grigory Konushev, Spidfire
Kotlin
6 Colecciones Ascension
Configurando la
7 Aaron Christiansen, elect, madhead
compilación de Kotlin
Equivalentes de flujo
13 Brad, Gerson, Jayson Minard, Piero Divasto, Sam
de Java 8
Extensiones Kotlin
15 Jemo Mgebrishvili, Ritave
para Android
Fundamentos de
17 Shinoo Goyal
Kotlin
https://riptutorial.com/es/home 107
18 Gamas Nihal Saxena
Instrumentos de
21 Januson, Sam
cuerda
23 JUIT jenglert
Kotlin para
24 desarrolladores de Thorsten Schleinzer
Java
Modificadores de
28 Avijit Karmakar
visibilidad
Parámetros Vararg
31 byxor, piotrek1543, Sam
en Funciones
Propiedades
32 Sam, Seaskyways
delegadas
RecyclerView en
33 Mohit Suthar
Kotlin
https://riptutorial.com/es/home 108
Tipo de
38 constructores Slav
seguros
https://riptutorial.com/es/home 109