El libro "Kotlin. Programación para profesionales "

imagen Hola habrozhiteli! El libro de Josh Skin y David Greenhall se basa en el popular curso Kotlin Essentials de Big Nerd Ranch. Ejemplos vívidos y útiles, explicaciones claras de conceptos clave y API fundamentales no solo introducen el lenguaje Kotlin, sino que también enseñan cómo usar sus capacidades de manera efectiva y también le permiten dominar el entorno de desarrollo JetBrains IntelliJ IDEA.

No importa si usted es un desarrollador experimentado que quiere ir más allá de Java, o si está aprendiendo el primer lenguaje de programación. Josh y David lo guiarán desde los principios básicos hasta el uso extendido de Kotlin para que pueda crear aplicaciones confiables y eficientes.


¿Para quién es este libro?


Nosotros (los autores) escribimos este libro para desarrolladores de diferentes calibres: desarrolladores experimentados de Android que carecen de funciones Java, desarrolladores de código de servidor interesados ​​en las funciones de Kotlin, y también para principiantes que deciden aprender un lenguaje compilado efectivo.

Este libro puede interesarle en admitir Android, pero no se limita a la programación en Kotlin para Android. Además, en este libro, solo un capítulo, el capítulo 21, analiza las técnicas de programación de Kotlin para Android. Sin embargo, si está interesado en el tema del uso de Kotlin para desarrollar aplicaciones de Android, este libro le presentará las técnicas básicas que simplificarán el proceso de escribir aplicaciones de Android en Kotlin.

Aunque Kotlin ha sido influenciado por otros idiomas, no necesita saber cómo están diseñados para funcionar con éxito con Kotlin. De vez en cuando, compararemos el código Java y Kotlin. Si tiene experiencia desarrollando en Java, esto lo ayudará a comprender la relación entre los dos idiomas. Y si no tiene esa experiencia, los ejemplos de resolución de los mismos problemas en otro idioma le ayudarán a comprender las ideas que influyeron en la formación de Kotlin.

Cómo usar este libro


Este libro no es una referencia. Nuestro objetivo es el aprendizaje constante del idioma Kotlin. Trabajará con proyectos y aprenderá el idioma en el proceso. Para un mayor efecto, le recomendamos que pruebe todos los ejemplos de código mientras lee el libro. Trabajar con ejemplos lo ayudará a desarrollar la memoria "muscular" y proporcionará ideas que le permitirán moverse de un capítulo a otro.

Cada capítulo siguiente se basa en el anterior. Recomendamos no saltear capítulos. Incluso si ha estudiado el tema mientras trabaja con otros idiomas, le sugerimos que al menos lea sobre esto aquí: muchas cosas se implementan de manera diferente en Kotlin. Comenzaremos con temas introductorios, como variables y listas, y luego pasaremos a las técnicas de programación funcional y orientada a objetos para que comprenda lo que hace de Kotlin una herramienta tan poderosa. Al final del libro, pasarás de ser un principiante a un desarrollador avanzado en Kotlin.

Queremos agregar que no debe darse prisa: desarrolle, use la documentación de Kotlin en el enlace: kotlinlang.org/docs/reference , donde hay respuestas a muchas preguntas que surgen durante los experimentos.

Extracto Extensiones


Las extensiones le permiten agregar funcionalidad a un tipo sin cambiar explícitamente la declaración de tipo. Use extensiones con tipos personalizados, así como con tipos sobre los que no tiene control, como List, String y otros tipos de la biblioteca estándar de Kotlin.
Las extensiones son una alternativa a la herencia. Son adecuados para agregar funcionalidad a un tipo si la definición de clase no está disponible para usted o si la clase no tiene un modificador abierto para permitir la subclasificación.

La biblioteca estándar de Kotlin a menudo usa extensiones. Por ejemplo, las funciones estándar que aprendió en el capítulo 9 son extensiones declaradas, y en este capítulo verá algunos ejemplos de su declaración.

En este capítulo, primero trabajaremos en un proyecto Sandbox y luego aplicaremos este conocimiento para optimizar el código NyetHack. Para comenzar, abra el proyecto Sandbox y cree un nuevo archivo llamado Extensions.kt.

Declaración de función de extensión


Su primera extensión le permite agregar cualquier grado de entusiasmo a String. Declararlo en Extensions.kt.

Listado 18.1. Agregar una extensión para el tipo String (Extensions.kt)

fun String.addEnthusiasm(amount: Int = 1) = this + "!".repeat(amount) 

Las funciones de extensión se declaran de la misma manera que otras funciones, pero con una diferencia: al definir una función de extensión, también se especifica un tipo conocido como tipo receptor al que la extensión agrega características. (Recuerde el Capítulo 9, donde llamamos a los tipos extensibles "receptores"). Para la función addEnthusiasm, se especifica un tipo de cadena de aceptación.

El cuerpo de la función addEnthusiasm es solo una expresión que devuelve una cadena: el contenido de este y 1 o más signos de exclamación, dependiendo del valor del argumento de cantidad (1 es el valor predeterminado). La palabra clave this se refiere a la instancia del objeto de destino para el que se llama la extensión (en este caso, la instancia de String).
Ahora puede llamar a la función addEnthusiasm para cualquier instancia de String. Pruebe una nueva función de extensión declarando una línea en la función principal y llamando a la función de extensión addEnthusiasm para que muestre el resultado.

Listado 18.2. Llamar a una nueva extensión para una instancia del objeto receptor String (Extensions.kt)

 fun String.addEnthusiasm(amount: Int = 1) = this + "!".repeat(amount) fun main(args: Array<String>) { println("Madrigal has left the building".addEnthusiasm()) } 

Ejecute Extensions.kt y vea si la función de extensión agrega un signo de exclamación a la cadena, según lo previsto.

¿Es posible subclasificar String para agregar esta capacidad a las instancias de String? En IntelliJ, mire el código fuente de la declaración de cadena presionando la tecla Shift dos veces para abrir el cuadro de diálogo Buscar en todas partes e ingrese "String.kt" en el cuadro de búsqueda. Verá esta declaración de clase:

 public class String : Comparable<String>, CharSequence { ... } 

Dado que la palabra clave abierta no está en la declaración de la clase String, no puede subclasificar String para agregar nuevas características a través de la herencia. Como se mencionó anteriormente, las extensiones son una buena opción si desea agregar funcionalidad a una clase que no puede administrar o no puede usar para crear una subclase.

Declaración de extensión de superclase


Las extensiones no dependen de la herencia, pero se pueden combinar con la herencia para aumentar el alcance. Pruebe esto en Extensions.kt: declare una extensión para el tipo Any con el nombre easyPrint. Dado que la extensión se declara para Any, estará disponible para todos los tipos. En general, reemplace la llamada a la función println con la llamada de extensión easyPrint a String.

Listado 18.3. Cualquier extensión (Extensions.kt)

 fun String.addEnthusiasm(amount: Int = 1) = this + "!".repeat(amount) fun Any.easyPrint() = println(this) fun main(args: Array<String>) { println("Madrigal has left the building".addEnthusiasm()).easyPrint() } 

Ejecute Extensions.kt y asegúrese de que la salida no haya cambiado.

Como agregó la extensión para Cualquier tipo, también está disponible para subtipos. Agregar una llamada de extensión para Int.

Listado 18.4. easyPrint está disponible para todos los subtipos (Extensions.kt)

 fun String.addEnthusiasm(amount: Int = 1) = this + "!".repeat(amount) fun Any.easyPrint() = println(this) fun main(args: Array<String>) { "Madrigal has left the building".addEnthusiasm().easyPrint() 42.easyPrint() } 

Funciones de extensión genérica


Pero, ¿qué pasa si desea imprimir la línea "Madrigal ha abandonado el edificio" antes y después de agregar entusiasmo?

Para hacer esto, agregue la capacidad de llamar en la cadena a la función easyPrint. Ya ha visto cadenas de llamadas a funciones: las funciones pueden participar en una cadena si devuelven un objeto receptor u otro objeto para el que se pueden llamar funciones posteriores.
Actualice easyPrint para llamar al encadenamiento.

Listado 18.5. Cambiar easyPrint para encadenar llamadas (Extensions.kt)

 fun String.addEnthusiasm(amount: Int = 1) = this + "!".repeat(amount) fun Any.easyPrint()= println(this): Any { println(this) return this } ... 

Ahora intente llamar a la función easyPrint dos veces: antes y después de agregar entusiasmo.

Listado 18.6. Llame a easyPrint dos veces (Extensions.kt)

 fun String.addEnthusiasm(amount: Int = 1) = this + "!".repeat(amount) fun Any.easyPrint(): Any { println(this) return this } fun main(args: Array<String>) { "Madrigal has left the building".easyPrint().addEnthusiasm().easyPrint() 42.easyPrint() } 

El código no se compiló. Se permitió la primera llamada de easyPrint, pero addEnthusiasm no. Mire la información de tipo para ver por qué sucede esto: haga clic en easyPrint y presione Control-Shift-P (Ctrl-P) y de la lista de extensiones que aparecen, seleccione el primero: ("Madrigal ha abandonado el edificio .easyPrint ()") (Fig. 18.1).

La función easyPrint devuelve la cadena para la que se llamó, pero usa el tipo Any para representarla. addEnthusiasm solo está disponible para String, por lo que no se puede invocar en el valor devuelto por easyPrint.

imagen

Para resolver este problema, puede hacer una extensión generalizada. Actualice la función de extensión easyPrint y use el tipo genérico como aceptador en lugar de Any.

Listado 18.7. Generalizando easyPrint (Extensions.kt)

 fun String.addEnthusiasm(amount: Int = 1) = this + "!".repeat(amount) fun <T> AnyT.easyPrint(): AnyT { println(this) return this } ... 

Ahora, cuando la extensión usa el parámetro del tipo generalizado T como el receptor y devuelve T en lugar de Cualquiera, la información sobre el tipo específico del objeto receptor se pasa por la cadena (Fig. 18.2).

imagen

Intente ejecutar Extensions.kt nuevamente. Esta vez la línea saldrá dos veces:

 Madrigal has left the building Madrigal has left the building! 42 

Su nueva función de extensión generalizada funciona con cualquier tipo y también procesa información al respecto. Las extensiones que usan tipos genéricos le permiten escribir funciones que pueden funcionar con una amplia variedad de tipos en un programa.

Las extensiones para tipos genéricos también están disponibles en la biblioteca estándar de Kotlin. Por ejemplo, mire la declaración de la función let:

 public inline fun <T, R> T.let(block: (T) -> R): R { return block(this) } 

let se declara como una función de extensión genérica, que le permite trabajar con todos los tipos. Toma una lambda que toma el objeto receptor como argumento (T) y devuelve el valor de algún tipo nuevo R.

Preste atención a la palabra clave en línea, que aprendimos en el Capítulo 5. El mismo consejo que le dimos anteriormente se aplica aquí: declarar una función de extensión como integrada, si acepta una lambda, reduce los costos de memoria.

»Se puede encontrar más información sobre el libro en el sitio web del editor
» Contenidos
» Extracto

25% de descuento en el cupón para Khabrozhitel - Kotlin
Tras el pago de la versión en papel del libro, se envía un libro electrónico por correo electrónico.

Source: https://habr.com/ru/post/464177/


All Articles