enumeración sellada: intercambio de enumeración en Kotlin Alex Vanyo | Livefront | Octubre de 2020

Las clases selladas son una de las poderosas herramientas de Kotlin para expresar jerarquías y enumerar la forma exacta en que se toman los datos. CON when palabra clave, trabajar con clases selladas puede ser simple y seguro sin problemas else rama. Cuando se introdujeron originalmente, especialmente a alguien del entorno Java, parecen enumeraciones aún más poderosas; La documentación oficial de Kotlin¹ establece que las clases selladas

son, en cierto sentido, una extensión de las clases de enumeración.

Desde que supe de las clases selladas, las he estado usando todo el tiempo. Las clases selladas anidadas le permiten expresar un estado complejo de una manera increíblemente poderosa, y su serialización y deserialización es fácil gracias a kotlinx. publicación por entregas. Los grados sellados genéricos permiten un manejo conveniente de envases convencionales, como State<T> oResult<T>.

Sin embargo, con todo lo que pueden hacer las clases selladas, todavía me encuentro escribiendo el siguiente código:

Por la forma en que lo usé ScrollingBehavior, Podría haberlo convertido fácilmente en una clase cerrada:

CON when, el código que consume la clase enum y la clase sellada sería casi idéntico. Entonces, ¿por qué necesitamos enumeraciones? Solo una clase cerrada de objetos es estrictamente una enumeración más poderosa: ambas son enumeraciones estáticas y finitas de algo. Al igual que la enumeración, una clase sellada puede tener argumentos de constructor o valores abstractos e implementar una interfaz. Sin embargo, las clases cerradas son mucho más flexibles que las clases de enumeración: pueden extender otras clases, tener argumentos de tipo general o formar parte de una jerarquía de clases cerradas anidadas.

En el escenario anterior, no tuve que lidiar con la lista completa ScrollingBehaviors. Si lo hubiera hecho, la clase enum sería un enfoque más conveniente debido a la existencia ScrollingBehavior.values(). Lograr el mismo resultado para las clases selladas no es tan simple. La única forma integrada es con KClass.sealedSubclasses que funciona pero requiere la reflexión de Kotlin, que puede ser inaceptablemente lenta en tiempo de ejecución. Una alternativa es mantener manualmente una lista de objetos, que también funciona pero a menudo es propensa a errores, ¡pero la estandarización se puede automatizar automáticamente!

Además, existe la oportunidad de un mejor tratamiento genérico porque el tratamiento genérico de las enumeraciones es doloroso. enumValuesOf<T>() funciona si es posible acceder al tipo de enumeración de forma cosificada, pero si no es así, la opción principal es pasar por Class enumeración para Class.getEnumConstants.

sealed-enum nació para resolver ambos problemas, y de hecho hizo obsoleta la definición de clases de enumeración reales en favor de clases cerradas de objetos, que yo llamo “enumeraciones selladas”. Inspirado en kotlinx.serialization KSerializer objetos que anotan el objeto acompañante de una clase sellada estructurada correctamente T con @GenSealedEnum resultará en una implementación generada SealedEnum<T>. Esta implementación es el objeto que proporciona values enumerar un ordinalOf método, herramientas Comparator basado en estos números de serie y también incluye nameOf y valueOf métodos:

Juntos, estos métodos corresponden a todas las funciones de clases de enumeración comunes.

Primero agreguemos un ejemplo de cómo funciona esto sealed-enum como la dependencia de Gradle de nuestro proyecto:

los sealed-enum La biblioteca consta de dos partes: una pequeña biblioteca en tiempo de ejecución que define anotaciones e interfaces, y un procesador de anotaciones para kapt.

Ahora que tenemos la biblioteca instalada, anotemos el objeto complementario recién creado para ScrollingBehavior clase sellada arriba:

El procesador de anotaciones luego genera un ScrollingBehaviorSealedEnum el objeto que implementa SealedEnum<ScrollingBehavior>, así como funciones de extensión y funciones fáciles de usar:

Ahora entendiéndolo ScrollingBehavior.values, o entregando SealedEnum Objeto alrededor directamente, tenemos todas las características que queremos de la enumeración y conservamos toda la potencia adicional que ofrecen las clases selladas.

La biblioteca en tiempo de ejecución y el procesador de anotaciones también tienen herramientas integradas para determinar el comportamiento y garantizar la interoperabilidad.

@GenSealedEnum se puede configurar para especificar el orden de rastreo, alternar entre rastreo en orden, preorden, posorden y nivel de orden para jerarquías de clases cerradas.

Para la interoperabilidad, hay una función integrada para ambas direcciones: primero, los métodos de creación están disponibles en la biblioteca de tiempo de ejecución SealedEnum un objeto dado por una clase de enumeración normal. Segundo, @GenSealedEnum se puede configurar para generar una clase de enumeración isomórfica que implemente todas las interfaces que realizan enumeraciones selladas a través de la delegación de interfaces. Si necesita especificar un valor de enumeración en una anotación o proporcionar una clase de enumeración real a alguna otra interfaz, puede mapear fácilmente entre dos representaciones según sea necesario.

Las clases de enumeración son excelentes, pero las clases selladas con objetos pueden ser mejores. Al generar la hoja estándar restante para llenar los vacíos, también puede mejorar sus enumeraciones a enumeraciones selladas y nunca volver a escribir una clase de enumeración normal.

Alex trabaja en Livefront, donde escribimos código para probar código para escribir código.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *