Una introducción a Kotlin
Introducción
Desde que Apple lanzó el lenguaje de Programación Swift para iOS, muchos
desarrolladores Android han querido un lenguaje similar para el desarrollo en
Android. Si eres uno de esos desarrolladores, te va a encantar Kotlin, un
lenguaje JVM que es notablemente similar a Swift.
Kotlin es un lenguaje tipado estáticamente, desarrollado por JetBrains, cuya
sintaxis es más expresiva y concisa que la de Java. Con características como
funciones orden superior, expresiones lambda, sobrecarga de operadores,
plantillas de string, y más, Kotlin tiene mucho más que ofrecer que Java.
Debido a que Java y Kotlin son altamente interoperables, pueden ser usados
juntos en el mismo proyecto.
Si eres un programador competente en Java, podrás aprender Kotlin en muy
poco tiempo. En éste tutorial te mostraré cómo usar las palabras reservadas
más frecuentemente usadas.
Requisitos Previos
Para continuar, necesitarás:
un buen entendimiento de Java.
la versión más reciente del compilador de Kotlin. Alternativamente,
podrías usar el patio de juegos online.
1. Clases
Para crear una clase en Kotlin, tienes que usar la palabra reservada class .
Por ejemplo, aquí te muestro como crear una clase llamada Person:
1 class Person {
2
3 }
Agregando Propiedades
Una clase generalmente tiene propiedades y funciones miembro (también
llamados métodos). Agreguemos dos propiedades a la clase Person , name de
tipo String y age de tipo Int .
1 var name: String = ""
2 var age: Int = 0
Como puedes ver, la sintaxis para crear variables es un poco diferente de la de
Java. Para crear una variable en Kotlin, debes usar la palabra reservada var .
Sin embargo, si quieres que tu variable sea una variable de solo lectura/una
única asignación, mejor utiliza la palabra reservada val .
Por el bien de la seguridad null, Kotlin también hace una distinción entre
variables que pueden ser null y variables que nunca pueden ser null . En
nuestro ejemplo previo, ambas variables name y age nunca pueden
ser null . Si son null, el compilador emitirá un error.
Para crear una variable que puede contener null , necesitas añadir
un ? después del tipo de la variable. Por ejemplo:
1 var college: String? = null
Ahora que tenemos una clase, crear una instancia de ella es fácil:
1 var jake = Person()
No, Kotlin no tiene la palabra reservada new . Una vez que la instancia ha
sido creada, puedes accesar a sus propiedades de la misma forma que lo harías
en Java:
1 [Link] = "Jake Hill"
2 [Link] = 24
3 [Link] = "Stephen's College"
Advertisement
Usar Constructores
Inicializando las propiedades individuales de nuestra instancia en la forma en
que lo acabamos de hacer no es una buena práctica en la codificación. Una
mejor forma de hacer ésto sería utilizando un constructor. La sintaxis de
Kotlin para crear tal constructor es muy compacta:
1 class Person(var name: String, var age: Int, var college: String?) {
2
3 }
De hecho, si no tienes nada que agregar a tu clase, no necesitas las llaves. El
siguiente código funciona bien:
1 class Person(var name: String, var age: Int, var college: String?)
2
3 var jake = Person("Jake Hill", 24, "Stephen's College")
Podría ya ser obvio para tí que no hay forma de que puedas agregar código
personalizado a éste constructor. Éste constructor, que es parte del encabezado
de la clase, es llamado el constructor primario.
Para agregar más constructores a tu clase, conocidos como constructores
secundarios, deberías usar la palabra reservada constructor . Los
constructores secundarios deberían delegar al constructor primario usando la
palabra reservada this . Agreguemos un constructor secundario a nuestra
clase que inicializa el valor de una propiedad llamada email:
1 class Person(var name: String, var age: Int, var college: String?) {
2
3 var email: String = ""
4
constructor(name:String, age:Int, college: String?, email: String) : this(name,
5 {
6 [Link] = email
7 }
8 }
Para crear una instancia que usa el constructor secundario, escribes algo como
ésto:
1 var jake = Person("Jake Hill", 24, "Stephen's College", "[Link]@[Link]")
Agregar Funciones Miembro
En Kotlin, las funciones son creadas usando la palabra reservada fun .
Agreguemos una función miembro simple llamada isElegibleToVote que
regrese un valor Boolean :
1 fun isEligibleToVote(): Boolean {
2 // If age is greater or equal to 18
3 // return true
4
5 return age >= 18
}
6
Nota que el tipo de valor retornado se indica al final del encabezado de la
función. Puedes llamara a éste método de la misma forma que lo harías en
Java:
1 [Link]()
Crear Extensiones
Kotlin te permite extender una clase al añadir funciones adicionales a ella sin
modificar su definición original. Tales funciones son conocidas como
extensiones. Los nombres de éstas funciones deberían ser precedidas por los
nombres de las clases de las que extienden.
Por ejemplo, para agregar una extensión llamada isTeenager a la
clase Person , escribe el siguiente código afuera de la clase:
1 fun [Link](): Boolean {
2
3 // If age falls in the range
4 // 13-19 return true
5
6 return age in 13..19
}
7
Ésta característica es especialmente útil cuando quieres extender clases que no
pertenecen al código base de tu proyecto. Por ejemplo, el siguiente fragmento
de código agrega una extensión containsSpaces a la clase String :
1 fun [Link](): Boolean {
2 return [Link](" ")!=-1
3 }
Advertisement
Crear Clases Derivadas
Es importante mantener lo siguiente en mente cuando se crea una clase
derivada:
Debes usar un : en lugar de la palabra reservada extends de Java.
El encabezado de la clase base debe tener la anotación open .
Si tu clase base tiene un constructor que toma parámetros, tu clase
derivada debe inicializar ésos parámetros en el mismo header.
Creemos una clase llamada Employee que deriva de Person :
1open class Person(var name: String, var age: Int, var college: String?) {
2 ...
}
3
4
5class Employee(name: String, age: Int, college: String?, var company:
String) : Person(name, age, college) {
6
7}
Sobreescribir Funciones Miembro
En Kotlin, tienes que señalar explícitamente que una función miembro puede
ser sobreescrita al usar la anotación open en el encabezado del método en la
clase base. En la clase derivada, funciones abiertas pueden ser sobreescritas
usando la anotación override .
Por ejemplo, para sobreescribir el método isElegibleToVote , agregas el
siguiente fragmento de código a la clase Employee :
1 override fun isEligibleToVote(): Boolean {
2 // Always return true
3 return true
}
4
Crear Métodos Estáticos
Kotlin no te permite crear métodos estáticos. Sin embargo, si te permite crear
un paquete de funciones nivel que no pertenecen a ninguna clase.
El método main es quizá el método estático mejor conocido. Si quieres
agregar el método main a un paquete llamado [Link],
entonces tu código se vería así:
1 package [Link]
2
3 fun main(args:Array<String>) {
4
5 }
2. Funciones
Ya aprendiste cómo crear funciones sencillas en los ejemplos previos. La
sintaxis que usaste para crear esas funciones fue muy similar a la de Java.
Kotlin, sin embargo, te permite hacer mucho más con funciones.
Crear Funciones de Expresión sencillas
Si una función regresa el valor de una expresión sencilla, entonces puedes
usar el operador = después del encabezado de la función seguido por la
expresión para definir la función.
Por ejemplo, para agregar un método a la clase Person que regresa true si
la persona es octogenaria, deberías escribir:
1 fun isOctogenarian(): Boolean = age in 80 .. 89
Como puedes ver, ésta sintaxis corta es más compacta y legible.
Funciones de Orden Superior y Expresiones Lambda
Funciones de orden superior son funciones que pueden regresar funciones o
aceptar funciones como parámetro. Una expresión lambda, por otro lado, es
sólo una función que no tiene nombre. Generalmente, expresiones lambda y
funciones de superior son usadas juntas.
Considera el siguiente ejemplo que demuestra la sintaxis de una expresión
lambda:
1 {x, y -> x+y}
Ésta es una simple expresión lambda que toma dos parámetros, x y y , y
regresa su suma. Como podrías haber supuesto, los parámetros de la función
son listados antes del operador -> y el cuerpo de la función comienza
después del operador -> . Ésta expresión lambda puede ser asignada a una
variable y usada como sigue:
1 val sumLambda: (Int, Int) -> Int = {x,y -> x+y}
2 val actualSum = sumLambda(3,4)
Nota que el tipo de la variable que contiene la expresión lambda especifica los
tipos de sus parámetros y su valor de retorno.
Crear una función de orden alta que puede aceptar la expresión lambda de
arriba como un parámetro es igual de fácil. Por ejemplo, para crear una
función que duplique el resultado de la expresión lambda, escribirías:
1 fun doubleTheResult(x:Int, y:Int, f:(Int, Int)->Int): Int {
2 return f(x,y) * 2
3 }
Puedes llamar a ésta función como sigue:
1 val result1 = doubleTheResult(3, 4, sumLambda)
Alternativamente, puedes pasar la expresión lambda directamente a la función
de orden superior:
1 val result2 = doubleTheResult(3, 4, {x,y -> x+y})
Las expresiones lambda son con frecuencia usadas con arrays (arreglos). Por
ejemplo, considera el siguiente array de valores Int :
1 val numbers:Array<Int> = arrayOf(1, 2, 3, 4, 5)
Si quieres elevar al cuadrado el valor de cada elemento en el array, puedes
usar la función map junto con una expresión lambda como sigue:
1 val squaredNumbers = [Link]({x -> x * x})
2
3 // Result will be a new array that contains
4 // 1, 4, 9, 16, 25
3. Rangos
Expresiones de rango son usadas muy frecuentemente en Kotlin. Ya las usaste
cuando creaste los métodos isTeenager y isOctogenarian .
Para crear un rango, todo lo que necesitas es el operador .. .
1 val r1 = 1..5
2
3 // This range contains the number 1, 2, 3, 4, 5
Para crear un rango en orden descendente, usa mejor la función downTo .
1 val r2 = 5 downTo 1
2
3 // This range contains the number 5, 4, 3, 2, 1
Si no quieres el paso que sea 1, puedes especificar un valor personalizado
usando la función step .
1 val r3 = 5 downTo 1 step 2
2
3 // This range contains the number 5, 3, 1
Verás más expresiones de rango posteriormente en éste tutorial.
4. Palabras reservadas condicionales
if
En Kotlin, if es una expresión que regresa diferentes valores dependiendo
de si la condición ha sido satisfecha. El siguiente ejemplo ilustra cómo
funciona ésto.
1 var age = 20
2 val isEligibleToVote = if(age > 18) "Yes" else "No"
3
4 // isEligibleToVote will now be set to "Yes"
when
La expresión when es equivalente a switch de Java. Sin embargo, es mucho
más versátil. Por ejemplo, considera el siguiente ejemplo.
01
val age = 17
02
03 val typeOfPerson = when(age){
04 0 -> "New born"
05 in 1..12 -> "Child"
06 in 13..19 -> "Teenager"
else -> "Adult"
07 }
08
09 // typeOfPerson will now be set to "Teenager"
10
Como puedes ver, when no puede tomar solo valores solos sino también
expresiones como sus condiciones.
5. La palabra reservada Looping
for.. in
En Kotlin, puedes usar el bucle for..in para iterar a través de arrays,
colecciones, y cualquier cosa que proporcione un iterador. Su sintaxis es casi
idéntica a la de Java, excepto por el uso del operador in en lugar del
operador : de Java. El siguiente ejemplo te muestra cómo iterar a través de
un array de objetos String .
1 val names = arrayOf("Jake", "Jill", "Ashley", "Bill")
2
3 for (name in names) {
4 println(name)
}
5
Con la ayuda de la expresiones de rango, puedes hacer que este bucle se
comporte como un tradicional bucle for de estilo-C.
1 for (i in 0..9) {
2 println(i)
3 }
4
5 // Behaves exactly like
// for(int i=0;i<10;i++)
6
while y do..while
La sintaxis de los bulces while y do..while en Kotlin es idéntica a la
sintaxis usada en Java. Por ejemplo, el siguiente código Kotlin itera en un
array de objetos String usando un bucle while :
1 val names = arrayOf("Jake", "Jill", "Ashley", "Bill")
2 var i = [Link]()
3
4 while(i>0) {
5 println(names[--i])
}
6
6. Plantillas de String
Kotlin te deja incrustar variables y expresiones en strings al encerrarlas en un
par de llaves, precedidas de un símbolo $ . Por ejemplo:
1 val name = "Bob"
2 println("My name is ${name}") // Prints "My name is Bob"
3
4 val a = 10
5 val b = 20
println("The sum is ${a+b}") // Prints "The sum is 30"
6
Conclusión
En éste tutorial, aprendiste las bases del lenguaje de programación Kotlin.
Aunque cubrimos varios constructores aquí, Kotlin tiene muchos mas que
ofrecer. De hecho, a partir de Junio de 2015, Kotlin aún está disponible
solamente como una vista previa. Es probable ver varias mejoras y nuevas
funcionalidades en los próximos meses.
Si quieres saber como usar Kotlin en Android Studio, entonces echa un
vistazo a Como Usar Kotlin en Tus Proyectos Android. Para aprender mas
sobre el lenguaje Kotlin, recomiendo visitar la documentación de Kotlin.
¡Sé el primero en conocer las nuevas traducciones–sigue @tutsplus_es en
Twitter!
Sintaxis básica
Definición e importación de paquetes
La especificación del paquete debe estar en la parte superior del archivo fuente.
package [Link]
import [Link].*
// ...
¡Copiado!
No es necesario que coincida con directorios y paquetes: los archivos de origen se
pueden colocar arbitrariamente en el sistema de archivos.
Ver paquetes .
Punto de entrada al programa
Un punto de entrada de una aplicación de Kotlin es la main función.
fun main () {
println ( "¡Hola mundo!" )
}
¡Hola Mundo!
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Otra forma de main acepta un número variable de String argumentos.
fun main ( args : Array < String > ) {
println ( args . contentToString ())
}
[]
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Imprime a la salida estándar
print imprime su argumento en la salida estándar.
print ( "Hola" )
print ( "mundo!" )
¡Hola Mundo!
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
println imprime sus argumentos y agrega un salto de línea, de modo que lo
siguiente que imprima aparezca en la siguiente línea.
println ( "¡Hola mundo!" )
println ( 42 )
¡Hola Mundo! 42
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Funciones
Una función con dos Intparámetros y Inttipo de retorno.
suma divertida ( a : Int , b : Int ): Int {
devolver a + b
}
suma de 3 y 5 es 8
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Un cuerpo de función puede ser una expresión. Se infiere su tipo de retorno.
suma divertida ( a : Int , b : Int ) = a + b
suma de 19 y 23 es 42
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Una función que no devuelve ningún valor significativo.
fun printSum ( a : Int , b : Int ): Unit {
println ( "la suma de $ ay $ b es $ {a + b}" )
}
suma de -1 y 8 es 7
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Unit se puede omitir el tipo de retorno.
fun printSum ( a : Int , b : Int ) {
println ( "la suma de $ ay $ b es $ {a + b}" )
}
suma de -1 y 8 es 7
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Ver funciones .
Variables
Las variables locales de solo lectura se definen mediante la palabra clave val. Solo
se les puede asignar un valor una vez.
val a : Int = 1 // asignación inmediata
val b = 2 // Se infiere el tipo `Int`
val c : Int // Tipo requerido cuando no se proporciona un inicializador
c = 3 // asignación diferida
a = 1, b = 2, c = 3
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Las variables que se pueden reasignar utilizan la varpalabra clave.
var x = 5 // Se infiere el tipo `Int`
x += 1
x = 6
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Puede declarar variables en el nivel superior.
val PI = 3,14
var x = 0
fun incrementX () {
x += 1
}
x = 0; PI = 3,14 incremento X () x = 1; PI = 3,14
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Consulte también Propiedades .
Creando clases e instancias
Para definir una clase, use la classpalabra clave.
class Shape
¡Copiado!
Las propiedades de una clase se pueden enumerar en su declaración o cuerpo.
class Rectangle(var height: Double, var length: Double) {
var perimeter = (height + length) * 2
}
¡Copiado!
El constructor predeterminado con los parámetros enumerados en la declaración
de clase está disponible automáticamente.
val rectangle = Rectángulo ( 5.0 , 2.0 )
println ( "El perímetro es $ {[Link]}" )
El perímetro es 14.0
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
La herencia entre clases se declara con dos puntos ( :). Las clases son definitivas
por defecto; para que una clase sea heredable, márquela como open.
open class Shape
class Rectangle(var height: Double, var length: Double): Shape() {
var perimeter = (height + length) * 2
}
¡Copiado!
Ver clases y objetos e instancias .
Comentarios
Al igual que la mayoría de los lenguajes modernos, Kotlin admite comentarios de
una sola línea (o final de línea ) y de varias líneas ( bloque ).
// This is an end-of-line comment
/* This is a block comment
on multiple lines. */
¡Copiado!
Los comentarios de bloque en Kotlin se pueden anidar.
/* The comment starts here
/* contains a nested comment */
and ends here. */
¡Copiado!
Consulte Documentación del código Kotlin para obtener información sobre la
sintaxis de los comentarios de la documentación.
Plantillas de cadenas
var a = 1
// nombre simple en la plantilla:
val s1 = "a es $ a"
a = 2
// expresión arbitraria en la plantilla:
val s2 = "$ {[Link] (" es "," era ")}, pero ahora es $ a"
a era 1, pero ahora es 2
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Consulte Plantillas de cadenas para obtener más detalles.
Expresiones condicionales
fun maxOf ( a : Int , b : Int ): Int {
si ( a > b ) {
devolver un
} más {
volver b
}
}
máximo de 0 y 42 es 42
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
En Kotlin, iftambién se puede utilizar como expresión.
fun maxOf ( a : Int , b : Int ) = if ( a > b ) a else b
máximo de 0 y 42 es 42
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Ver if-expresiones .
En bucle
val items = listOf ( "manzana" , "plátano" , "kiwi" )
para ( elemento en elementos ) {
println ( artículo )
}
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
o
val items = listOf ( "manzana" , "plátano" , "kiwi" )
para ( índice en elementos . índices ) {
println ( "el elemento en $ índice es $ {elementos [índice]}" )
}
artículo en 0 es manzana artículo en 1 es plátano artículo en 2 es kiwi
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Consulte el bucle .
Mientras que bucle
val items = listOf ( "manzana" , "plátano" , "kiwi" )
var index = 0
while ( índice < elementos . tamaño ) {
println ( "el elemento en $ índice es $ {elementos [índice]}" )
índice ++
}
artículo en 0 es manzana artículo en 1 es plátano artículo en 2 es kiwi
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Ver bucle while .
Cuando expresión
fun describe ( obj : Any ): String =
cuando ( obj ) {
1 -> "Uno"
"Hola" -> "Saludo"
es largo -> "largo"
! es String -> "No es una cadena"
más -> "Desconocido"
}
Un saludo largo No es una cadena Desconocido
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Ver cuando expresión .
Rangos
Verifique si un número está dentro de un rango usando el inoperador.
val x = 10
val y = 9
si ( x en 1 .. y + 1 ) {
println ( "encaja en el rango" )
}
encaja en el rango
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Compruebe si un número está fuera de rango.
val list = listOf ( "a" , "b" , "c" )
if ( - 1 ! in 0 .. list . lastIndex ) {
println ( "-1 está fuera de rango" )
}
if ( list . size ! in list . indices ) {
println ( "el tamaño de la lista también está fuera del rango de índices de lista
válido" )
}
-1 está fuera del rango El tamaño de la lista también está fuera del
rango de índices de lista válido
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Itera sobre un rango.
para ( x en 1 .. 5 ) {
imprimir ( x )
}
12345
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
O sobre una progresión.
para ( x en 1 .. 10 paso 2 ) {
imprimir ( x )
}
println ()
para ( x en 9 hasta 0 paso 3 ) {
imprimir ( x )
}
13579 9630
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Consulte Rangos y progresiones .
Colecciones
Repita una colección.
para ( elemento en elementos ) {
println ( artículo )
}
kiwi manzana banana
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Compruebe si una colección contiene un objeto usando el inoperador.
cuando {
"naranja" en elementos -> println ( "jugoso" )
"manzana" en elementos -> println ( "manzana también está bien" )
}
la manzana también está bien
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Usando expresiones lambda para filtrar y mapear colecciones:
val frutos = listof ( "banana" , "aguacate" , "manzana" , "kiwi" )
frutas
. filtrar { it . startsWith ( "a" )}
. sortedBy { it }
. map { it . mayúscula ()}
. forEach { println ( it )}
AGUACATE DE MANZANA
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Consulte Descripción general de las colecciones .
Valores que aceptan valores NULL y
comprobaciones nulas
Una referencia debe marcarse explícitamente como anulable cuando el nullvalor
sea posible. Los nombres de tipos que aceptan valores NULL tienen ?al final.
Devuelve nullsi strno contiene un número entero:
fun parseInt(str: String): Int? {
// ...
}
¡Copiado!
Utilice una función que devuelva un valor anulable:
fun printProduct ( arg1 : String , arg2 : String ) {
val x = parseInt ( arg1 )
val y = parseInt ( arg2 )
// El uso de `x * y` produce un error porque pueden contener valores nulos.
si ( x ! = nulo && y ! = nulo ) {
// xey se convierten automáticamente en no anulables después de la verificación nula
println ( x * y )
}
else {
println ( "'$ arg1' o '$ arg2' no es un número" )
}
}
42 'a' o '7' no es un número 'a' o 'b' no es un número
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
// ...
si ( x == nulo ) {
println ( "Formato de número incorrecto en arg1: '$ arg1'" )
regreso
}
si ( y == nulo ) {
println ( "Formato de número incorrecto en arg2: '$ arg2'" )
regreso
}
// xey se convierten automáticamente en no anulables después de la verificación nula
println ( x * y )
42 Formato de número incorrecto en arg1: 'a' Formato de número incorrecto
en arg2: 'b'
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Consulte Seguridad nula .
Comprobaciones de tipo y lanzamientos
automáticos
El isoperador comprueba si una expresión es una instancia de un tipo. Si se
comprueba una propiedad o variable local inmutable para un tipo específico, no es
necesario convertirla explícitamente:
fun getStringLength ( obj : Any ): Int ? {
if ( obj es String ) {
// `obj` se convierte automáticamente en` String` en esta rama
return obj . largo
}
// `obj` sigue siendo de tipo` Any` fuera de la rama de tipo verificado
devolver nulo
}
Obtener la longitud de 'Incomprensibilidades'. Resultado: 21 Obtener la
longitud de '1000'. Resultado: Error: El objeto no es una cadena.
Obteniendo la longitud de '[[Link]@2a84aee7]'. Resultado:
Error: el objeto no es una cadena
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
fun getStringLength ( obj : Any ): Int ? {
if ( obj ! is String ) return null
// `obj` se convierte automáticamente en` String` en esta rama
return obj . largo
}
Obtener la longitud de 'Incomprensibilidades'. Resultado: 21 Obtener la
longitud de '1000'. Resultado: Error: El objeto no es una cadena.
Obteniendo la longitud de '[[Link]@2a84aee7]'. Resultado:
Error: el objeto no es una cadena
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
o incluso
fun getStringLength ( obj : Any ): Int ? {
// `obj` se convierte automáticamente en` String` en el lado derecho de `&&`
if ( obj es String && obj . length > 0 ) {
return obj . largo
}
devolver nulo
}
Obtener la longitud de 'Incomprensibilidades'. Resultado: 21 Obtener la
longitud de ''. Resultado: Error: El objeto no es una cadena. Obteniendo
la longitud de '1000'. Resultado: Error: el objeto no es una cadena
Plataforma de destino: JVM que se ejecuta en kotlin v. 1.5.0
Consulte Conversiones de clases y tipos .
Modismos
Una colección de modismos aleatorios y de uso frecuente en Kotlin. Si tiene un
modismo favorito, contribuya con él enviando una solicitud de extracción.
Crear DTO (POJO / POCO)
data class Customer(val name: String, val email: String)
¡Copiado!
proporciona una Customerclase con la siguiente funcionalidad:
getters (y setters en caso de vars) para todas las propiedades
equals()
hashCode()
toString()
copy()
component1(),, component2()..., para todas las propiedades (ver Clases de datos )
Valores predeterminados para parámetros de
función
fun foo(a: Int = 0, b: String = "") { ... }
¡Copiado!
Filtrar una lista
val positives = [Link] { x -> x > 0 }
¡Copiado!
O alternativamente, incluso más corto:
val positives = [Link] { it > 0 }
¡Copiado!
Verificar la presencia de un elemento en una
colección
if ("john@[Link]" in emailsList) { ... }
if ("jane@[Link]" !in emailsList) { ... }
¡Copiado!
Interpolación de cadenas
println("Name $name")
¡Copiado!
Comprobaciones de instancia
when (x) {
is Foo -> ...
is Bar -> ...
else -> ...
}
¡Copiado!
Lista de solo lectura
val list = listOf("a", "b", "c")
¡Copiado!
Mapa de solo lectura
val map = mapOf("a" to 1, "b" to 2, "c" to 3)
¡Copiado!
Acceder a una entrada de mapa
println(map["key"])
map["key"] = value
¡Copiado!
Recorre un mapa o una lista de pares
for ((k, v) in map) {
println("$k -> $v")
}
¡Copiado!
ky vpuede ser cualquier nombre conveniente, como namey age.
Iterar sobre un rango
for (i in 1..100) { ... } // closed range: includes 100
for (i in 1 until 100) { ... } // half-open range: does not include 100
for (x in 2..10 step 2) { ... }
for (x in 10 downTo 1) { ... }
if (x in 1..10) { ... }
¡Copiado!
Propiedad perezosa
val p: String by lazy {
// compute the string
}
¡Copiado!
Funciones de extensión
fun [Link]() { ... }
"Convert this to camelcase".spaceToCamelCase()
¡Copiado!
Crea un singleton
object Resource {
val name = "Name"
}
¡Copiado!
Crear una instancia de una clase abstracta
abstract class MyAbstractClass {
abstract fun doSomething()
abstract fun sleep()
}
fun main() {
val myObject = object : MyAbstractClass() {
override fun doSomething() {
// ...
}
override fun sleep() { // ...
}
}
[Link]()
}
¡Copiado!
Taquigrafía if-not-null
val files = File("Test").listFiles()
println(files?.size) // size is printed if files is not null
¡Copiado!
Abreviatura de if-not-null-else
val files = File("Test").listFiles()
println(files?.size ?: "empty") // if files is null, this prints "empty"
¡Copiado!
Ejecutar una declaración si es nulo
val values = ...
val email = values["email"] ?: throw IllegalStateException("Email is missing!")
¡Copiado!
Obtener el primer elemento de una colección
posiblemente vacía
val emails = ... // might be empty
val mainEmail = [Link]() ?: ""
¡Copiado!
Ejecutar si no es nulo
val value = ...
value?.let {
... // execute this block if not null
}
¡Copiado!
Asignar valor anulable si no es nulo
val value = ...
val mapped = value?.let { transformValue(it) } ?: defaultValue
// defaultValue is returned if the value or the transform result is null.
¡Copiado!
Declaración de devolución cuando
fun transform(color: String): Int {
return when (color) {
"Red" -> 0
"Green" -> 1
"Blue" -> 2
else -> throw IllegalArgumentException("Invalid color param value")
}
}
¡Copiado!
expresión try-catch
fun test() {
val result = try {
count()
} catch (e: ArithmeticException) {
throw IllegalStateException(e)
}
// Working with result
}
¡Copiado!
si expresión
fun foo(param: Int) {
val result = if (param == 1) {
"one"
} else if (param == 2) {
"two"
} else {
"three"
}
}
¡Copiado!
Uso de métodos al estilo constructor que devuelven
Unit
fun arrayOfMinusOnes(size: Int): IntArray {
return IntArray(size).apply { fill(-1) }
}
¡Copiado!
Funciones de expresión única
fun theAnswer() = 42
¡Copiado!
Esto es equivalente a
fun theAnswer(): Int {
return 42
}
¡Copiado!
Esto se puede combinar eficazmente con otros modismos, lo que lleva a un código
más corto. Por ejemplo, con la whenexpresión:
fun transform(color: String): Int = when (color) {
"Red" -> 0
"Green" -> 1
"Blue" -> 2
else -> throw IllegalArgumentException("Invalid color param value")
}
¡Copiado!
Llamar a varios métodos en una instancia de objeto
(con)
class Turtle {
fun penDown()
fun penUp()
fun turn(degrees: Double)
fun forward(pixels: Double)
}
val myTurtle = Turtle()
with(myTurtle) { //draw a 100 pix square
penDown()
for (i in 1..4) {
forward(100.0)
turn(90.0)
}
penUp()
}
¡Copiado!
Configurar propiedades de un objeto (aplicar)
val myRectangle = Rectangle().apply {
length = 4
breadth = 5
color = 0xFAFAFA
}
¡Copiado!
Esto es útil para configurar propiedades que no están presentes en el constructor
de objetos.
Prueba con recursos de Java 7
val stream = [Link]([Link]("/some/[Link]"))
[Link]().reader().use { reader ->
println([Link]())
}
¡Copiado!
Función genérica que requiere la información de
tipo genérico
// public final class Gson {
// ...
// public <T> T fromJson(JsonElement json, Class<T> classOfT) throws JsonSyntaxException {
// ...
inline fun <reified T: Any> [Link](json: JsonElement): T = [Link](json, T::[Link])
¡Copiado!
Booleano que admite valores NULL
val b: Boolean? = ...
if (b == true) {
...
} else {
// `b` is false or null
}
¡Copiado!
Intercambia dos variables
var a = 1
var b = 2
a = [Link] { b = a }
¡Copiado!
Marcar el código como incompleto (TODO)
La biblioteca estándar de Kotlin tiene una TODO()función que siempre arrojará
un NotImplementedError. Su tipo de retorno es Nothingpara que pueda usarse
independientemente del tipo esperado. También hay una sobrecarga que acepta
un parámetro de motivo:
fun calcTaxes(): BigDecimal = TODO("Waiting for feedback from accounting")
¡Copiado!
El complemento kotlin de IntelliJ IDEA comprende la semántica TODO()y agrega
automáticamente un puntero de código en la ventana de la herramienta TODO.