Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin: How to extend the enum class with an extension function

I'm trying to extend enum classes of type String with the following function but am unable to use it at the call site like so:

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);

What am I doing wrong here?

like image 555
geg Avatar asked Mar 13 '16 04:03

geg


2 Answers

I suggest following solution:

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()
}

Instead of attaching extension function to Class, i attached it to KotlinClass.

Now, you can simply use it:

enum class Test {ONE, TWO, THREE }

fun main(args: Array<String>) {
    println(Test::class.join())
}
// ONE, TWO, THREE
like image 73
Ruslan Avatar answered Sep 18 '22 12:09

Ruslan


@IRus' answer is correct but you don't have to use reflection. For every enum class, a values() method is automatically generated by the compiler. This method returns an array containing all the entries. We can make the extension function operate directly on this array like this:

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

And call it like this:

fun main(args: Array<String>) {
    Test.values().join()
}
like image 42
Kirill Rakhman Avatar answered Sep 21 '22 12:09

Kirill Rakhman