Muy buenas, soy Miguel y en esta ocasión les traigo un nuevo artículo.
Índice
Funciones exclusivas de Kotlin que deberías usar
Kotlin es un lenguaje amigable para los desarrolladores y hace que el trabajo (desarrollo) más desafiante del mundo sea un trabajo divertido, sin importar en qué plataforma esté trabajando. Con Kotlin, puede crear su estilo de código.
Si no ha leído la primera parte, le recomiendo que la lea. El primer artículo contiene una guía detallada sobre cómo utilizar funciones potentes y útiles de Kotlin, como extensiones, funciones de orden superior y de alcance.
Habiendo dicho eso, ¿qué vas a aprender en este artículo? Digamos que no podemos encajar las funciones ocultas pero poderosas de Kotlin en uno o dos artículos.
Empecemos a aprender.
Delegados de Kotlin
Un delegado es solo una clase que proporciona el valor de una propiedad y maneja sus cambios. Esto nos permite mover, o delegar, la lógica getter-setter
de la propiedad en sí a una clase separada, permitiéndonos reutilizar esta lógica.
Veamos un ejemplo sencillo.
class Sample { var str_sample : String = "" set(value) { field = value.trim() } }
Ejemplo de delegado simple.
Si tiene alguna duda con la sintaxis, consulte Kotlin Docs aquí.
Lo que sucede aquí es que podemos asignar un valor a la variable str_sample
como se muestra arriba, pero la ventaja de escribir esto es que no es necesario escribir .trim ()
cada vez.
Puede crear extensiones o clases personalizadas para aplicar esto aún más rápidamente. Leer part1
para saber cómo crear extensiones.
¿No es genial? Quizás te preguntes algo como que es dulce pero no muy útil.
Estás equivocado, es super útil, veamos cómo.
¿Recuerdan cómo escribimos las funciones put
y get
de preferencias compartidas? Permítanme refrescar su memoria con una muestra.
fun getAccessToken(): String { return sharedPreferenceHelper.getString(Constants.ACCESS_TOKEN, "") } fun setAccessToken(value : String) { sharedPreferenceHelper.edit().putString(Constants.ACCESS_TOKEN, value).apply() }
Preferencia sin delegados.
¿Podemos reducir el código y hacer que parezca inteligente? Por supuesto que podemos,
var accessToken: String get() = sharedPreferenceHelper.getString(Constants.ACCESS_TOKEN,"") set(accessToken) = sharedPreferenceHelper.setString(Constants.ACCESS_TOKEN, accessToken)
Preferencia con los delegados.
Ahora, veamos cómo podemos usar estos delegados con otros componentes. Si observa lo que estamos haciendo aquí cuidadosamente, puede ver que estamos guardando un valor en una variable y recuperando el valor más tarde cuando sea necesario.
Podemos aprovechar esta funcionalidad e implementar guardar y recuperar valores del paquete en fragmentos de manera más fácil.
Veamos cómo guardamos y recuperamos valores del paquete en fragmentos.
//saving values into bundle arguments = Bundle().apply { putInt(Constants.CutomerID, id) putString(Constants.CutomerName, name) } //retrining values from bundle arguments?.let { args -> id = args.getInt(Constants.CutomerID) name = args.getString(Constants.CutomerName) }
Agrupar operaciones sin delegados.
Lo que hicimos aquí es que guardamos los valores en el paquete y luego asignamos ese paquete al fragmento mientras creamos y luego recuperamos los valores del paquete en función OnCreate
.
Primero, creemos una extensión para insertar valores en el paquete para que no necesitemos invocar diferentes funciones basadas en el tipo de datos. Echar un vistazo.
fun <T> Bundle.put(key: String, value: T) { when (value) { is Boolean -> putBoolean(key, value) is String -> putString(key, value) is Int -> putInt(key, value) is Short -> putShort(key, value) is Long -> putLong(key, value) is Byte -> putByte(key, value) is ByteArray -> putByteArray(key, value) is Char -> putChar(key, value) is CharArray -> putCharArray(key, value) is CharSequence -> putCharSequence(key, value) is Float -> putFloat(key, value) else -> throw IllegalStateException("Type of property $key is not supported") } }
Extensión de Kotlin para insertar valores en paquetes.
Luego, necesitamos crear una clase que amplíe ReadWriteProperty
y anule el conjunto y obtenga funciones como se muestra a continuación para guardar y recuperar valores en tiempo real. Echar un vistazo.
class FragmentBundleDataDelegate<T : Any> : ReadWriteProperty<Fragment, T> { @Suppress("UNCHECKED_CAST") override fun getValue( thisRef: Fragment, property: KProperty<*> ): T { val key = property.name return thisRef.arguments ?.get(key) as?T ?: throw IllegalStateException("") }
override fun setValue( thisRef: Fragment, property: KProperty<*>, value: T ) { val args = thisRef.arguments ?: Bundle().also(thisRef::setArguments) val key = property.name args.put(key, value) } }
Clase de delegado personalizada para automatizar la funcionalidad del paquete en fragmentos.
Ahora cree una función para simplificar el proceso de uso de la clase anterior y también fácil de entender para los nuevos desarrolladores en su proyecto.
fun <T : Any> argument(): ReadWriteProperty<Fragment, T> = FragmentArgumentDelegate()
Ahora es el momento de utilizar este delegado y ver cómo nos facilita la vida.
class CustomerFragment : Fragment() { private var id : Int by argument() private var name : String by argument() companion object { fun getInstance(mId: Int, nName: String): CustomerFragment = CustomerFragment().apply { this.id = mId this.name = nName } } }
Manejo de valores de paquete con delegados de Kotlin.
Eso es todo lo que ni siquiera necesita escribir ningún código para poner u obtener valores del paquete. Ahora no es tan impresionante.
Parámetros predeterminados y con nombre en funciones
Kotlin tiene muchas características útiles y subestimadas, estoy seguro de que esta es una de ellas.
Digamos que tenemos que escribir una función que calcule la suma de dos valores. La parte complicada aquí es que el usuario puede pasar ambos valores o cualquiera de los valores o nada.
Estoy seguro de que Java puede manejar esto como se muestra a continuación.
public void add(int a, int b) : Int{ return a + b } public void add(int a) : Int{ return this.add(a, 0); } public void add() : Int { return this.add(0, 0); }
Ahora, veamos cómo podemos manejar esto en Kotlin.
fun add(a : Int = 0, b : Int = 0) = a + b
¿No es fantástico? Una función con parámetros que tienen valores predeterminados. Sólo puede pasar a
o b
valor en función de sus necesidades.
Ahora, como se puede pasar solo a
o b
valores cuando la función tiene dos parámetros. ¿Cómo sabrá la función qué valor está pasando?
Esta es otra característica útil de Kotlin; podemos pasar un parámetro usando sus nombres en la función real. Echar un vistazo.
add() // no values are passed so both will 0 by default add(12,13) // Both values are passed add(a = 12) // only a value is passed and b will be 0 by default add(b = 13) // only b value is passed and a will be 0 by default add(b = 13, a = 12) // You don't need to maintain sequence when using named parameters
Funciones en línea para usar funciones de orden superior de manera efectiva
En Kotlin, las funciones de orden superior y los lambads se almacenan como objetos, por lo que es un consumo de memoria y las llamadas virtuales pueden introducir una sobrecarga en el tiempo de ejecución.
A veces podemos eliminar la sobrecarga de memoria insertando el código de las funciones de orden superior.
La función en línea le dice al compilador que copie parámetros y funciones al sitio de llamada.
Digamos que la siguiente impresión es una función en línea.
public inline fun print(message: String) { System.out.print(message) }
Ahora invoquemos la función de impresión desde otra función, eche un vistazo.
fun normalFunction(){ print("Hello") print("world") }
Así es como aparece antes de la compilación, cuando declaramos una función ya que el compilador en línea la trata de manera diferente.
Durante la compilación, reemplaza la llamada a la función con declaraciones reales en esa función. Eche un vistazo al cuerpo de función normal después de la compilación.
fun normalFunction(){ System.out.print("Hello") System.out.print("world") }
Para que no se guarden objetos en la memoria, y ejecuta las declaraciones paso a paso como lo hace la función normal, lo que conduce a un mejor rendimiento.
La poderosa when
declaración en Kotlin
El enfoque principal de la when
declaración en Kotlin es proporcionar una funcionalidad similar a la declaración switch
. Mientras que la funcionalidad switch
está restringida a ciertas limitaciones como comparar el valor y ejecutar diferentes bloques de código.
Pero when
tiene una plétora de funcionalidades útiles como puede devolver el valor o ejecutar bloques de código basados en los valores.
Veamos cómo ejecutar un bloque when
normal.
when(number) { 0 -> println("apple") 1, 2 -> println("banana") 3 -> println("grape") 4 -> println("Orange") else -> println("Not a fruite") }
When
sustituye default
la palabra clave en switch
a else
pero la funcionalidad es similar. En mi opinión else
encaja en la sintaxis que default
.
Ahora, veamos cómo devolver un valor usando declaración when
.
tv_name.text = when(number) { 0 -> "apple" 1, 2 -> "banana" 3 -> "grape" 4 -> "Orange" else -> "Not a fruite" }
When con valor de retorno.
Este tipo de funcionalidad no es posible en Java.
When
no solo admite comparaciones constantes simples, también admite condiciones internas como rango de números como se muestra a continuación.
tv_name.text = when(number) { 0 -> "apple" 1, 2 -> "banana" in 3..7 -> "grape" !in 8..12 -> "Orange" else -> "Not a fruite" }
When con condiciones arbitrarias.
La belleza de when
es que podemos usarlo incluso sin discutir. En este caso, actúa como un if/else
bloque simple , pero la ventaja aquí es que proporciona una interfaz más limpia y fácil de entender.
when { number > 1 -> print("apple") text == "apple" -> print("This is apple") }
When sin argumento.
Gracias por leer este artículo.
Añadir comentario