¿Cómo extiendo la class Kotlin Number o uso generics para crear un getter de propiedad simple que operará en todas las subclasss Number?
Estoy tratando de aprender más sobre extensiones de classs abstractas de Kotlin y generics mediante la construcción de methods muy simples y captadores de properties que extienden las classs integradas. En su mayoría he tenido éxito, pero estoy confundido por la class Número. Mi propiedad de testing Number.sgn
está destinada a devolver el signo (1 o -1 como Int) de cualquier subclass de Number. Para simplificar, los negativos deberían devolver -1, mientras que los numbers positivos y 0 deberían ser 1. No estoy particularmente interesado en el caso de uso de este método, sino en la comprensión de cómo escribir algo simple como este, y por qué mi código genera el error lo hace. La única import en mi module es kotlin.text.*
Y el post de error que recibo se refiere a un conflicto allí. Simplemente no entiendo por qué entra en conflicto y cómo superarlo, aunque supongo que es un error de novato.
Primero escribí el código para extender la class Int, que funciona bien:
- Métodos de interfaz de anulación de Android kotlin dentro del método onCreateView ()
- Problema con el método de extensión en el script de Kotlin
- Choque de extensión Kotlin
- Kotlin: ¿Cómo ejecutar methods de service en el context de una class de transacción?
- Funciones de extensión para classs genéricas en Kotlin
inline val Int.sgn get() = if (this<0) -1 else 1 // sign of number
Luego intenté generalizar y moverlo a la class Número, así:
inline val Number.sgn get() = if (this<0) -1 else 1 // doesn't compile
y el error de compilation es el siguiente:
unresolved reference. None of the following candidates is applicable because of receiver type mismatch: public fun String.compareTo(other: String, ignoreCase: Boolean = ...): Int defined in kotlin.text inline fun Number.sgn() = if (this<0) -1 else 1 ^
Luego intenté un enfoque diferente, usando generics:
inline val <T:Number> T.sgn get() = if (this<0) -1 else 1
y recibí el mismo error del comstackdor:
error: unresolved reference. None of the following candidates is applicable because of receiver type mismatch: public fun String.compareTo(other: String, ignoreCase: Boolean = ...): Int defined in kotlin.text inline val <T:Number> T.sgn get() = if (this<0) -1 else 1 ^
¿Alguien podría ayudarme a entender por qué hay un desajuste de tipo y por qué kotlin.text
importa aquí? ¿Existe un enfoque que podría utilizar para solucionar este problema y hacer que este getter de properties se aplique a todas las subclasss de Number? (Una vez más, sé que este no es un caso de uso significativo, sino más bien un ejemplo simplificado que me ayuda a comprender los principios que lo explican). Gracias de antemano por cualquier consejo que alguien pueda dar …
- Función de queue Kotlin List
- Genéricos para RecyclerView.Adapter Android
- ¿Puedo crear un método de extensión Kotlin para agregar una suscripción rxJava a una suscripción compuesta?
- Miembro de Kotlin y extensión al mismo time
- Tokens inesperados (uso; para separar expresiones en la misma línea)
- Las funciones de extensión de Kotlin de repente requieren un nivel de api 24
- Kotlin: ¿Cuando la function de extensión oculta la implementación pnetworkingeterminada de la class?
- acceso al método de extensión kotlin en otro kt
Su primera function funciona porque Int
implementa Comparable<Int>
, eso es a lo que se traduce el operador <
. Sin embargo, si observas la class Number
, verás que solo tiene funciones para las conversiones a sus diversas subclasss; no implementa Comparable
, por lo tanto, no puedes usar el operador <
en ella.
Lo que podría hacer en su lugar es convertir su Number
a un Double
primero, y luego ver si es negativo:
inline val <T : Number> T.sgn get() = if (this.toDouble() < 0) -1 else 1
También podría hacer que su código original (con o sin generics) funcione implementando la function compareTo
para Number
como una extensión:
operator fun Number.compareTo(other: Number) = this.toDouble().compareTo(other.toDouble())
Solo ten en count que lanzar todo a Double
puede resultar en perder precisión.
- La demostración IOU de Corda V1.0 no funciona en Windows
- Base de datos de Firebase serialize int to enum?