Kotlin: Cómo extender la class enum con una function de extensión

Estoy tratando de extender las classs enum de tipo String con la siguiente function, pero no puedo usarla en el sitio de la llamada como esta:

 fun <T: Enum<String>> Class<T>.join(skipFirst: Int = 0, skipLast: Int = 0): String { return this.enumConstants .drop(skipFirst) .dropLast(skipLast) .map { e -> e.name } .joinToString() } MyStringEnum.join(1, 1); 

¿Qué estoy haciendo mal aquí?

Sugiero seguir la solución:

 fun <T : Enum<*>> KClass<T>.join(skipFirst: Int = 0, skipLast: Int = 0): String { return this.java .enumConstants .drop(skipFirst) .dropLast(skipLast) .map { e -> e.name } .joinToString() } 

En lugar de unir la function de extensión a Clase, la adjunté a KotlinClass.

Ahora, simplemente puede usarlo:

 enum class Test {ONE, TWO, THREE } fun main(args: Array<String>) { println(Test::class.join()) } // ONE, TWO, THREE 

Reescribiré tu unión ligeramente así con un comodín:

 fun <T: Enum<*>> Class<T>.join(skipFirst: Int = 0, skipLast: Int = 0): String { return this.enumConstants .drop(skipFirst) .dropLast(skipLast) .map { e -> e.name } .joinToString() } 

Entonces, suponiendo que MyStringEnum se define así:

 enum class MyStringEnum { FOO, BAR, BAZ } 

Puedes llamarlo así:

 println(MyStringEnum.values()[0].javaClass.join()) 

para get la salida "FOO, BAR, BAZ"

Como está definiendo join en Class, necesita un object Class real para invocarlo. Las classs Enum aparentemente no funcionan así, pero sus enumeraciones definidas pueden producir una Clase con javaClass . Así que esto es lo mejor que se me ocurre que creo que cumple con el espíritu general de su request. No sé si hay una manera más elegante de lograr lo que estás tratando de hacer para todas las classs enum como esta.

EDITAR: Puede ajustar esto un poco más con esto:

 fun Enum<*>.join(skipFirst: Int = 0, skipLast: Int = 0): String { return this.javaClass.join(skipFirst, skipLast) } 

Que te permite llamar así:

 println(MyStringEnum.values()[0].join()) 

La respuesta de @IRus es correcta, pero no es necesario usar la reflexión. Para cada class enum, el comstackdor genera automáticamente un método values() . Este método devuelve una matriz que contiene todas las inputs. Podemos hacer que la function de extensión opere directamente en esta matriz como esta:

 fun <T : Enum<*>> Array<T>.join(skipFirst: Int = 0, skipLast: Int = 0) = drop(skipFirst) .dropLast(skipLast) .map { e -> e.name } .joinToString() 

Y llámalo así:

 fun main(args: Array<String>) { Test.values().join() } 
  • El resultado es el mismo, pero el caso de testing no pasa en la testing unitaria
  • acceso al método de extensión kotlin en otro kt
  • Crear nueva instancia de object Kotlin
  • ¿Hay alguna diferencia entre "object receptor" y "receptor de extensión"
  • Kotlin crea problemas con Android
  • ¿Convertir mi proyecto de estudio andorid existente a kotlin?
  • ¿Cómo verificar la class "instanceof" en kotlin?
  • Cómo mantener el tipo de object para el casting inteligente al devolver cualquier