14

次の関数を使用して型の列挙型クラスを拡張しようとしてStringいますが、次のように呼び出しサイトで使用できません。

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

ここで何が間違っていますか?

4

4 に答える 4

16

次の解決策をお勧めします。

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

クラスに拡張機能を付ける代わりに、KotlinClass に付けました。

今、あなたはそれを簡単に使うことができます:

enum class Test {ONE, TWO, THREE }

fun main(args: Array<String>) {
    println(Test::class.join())
}
// ONE, TWO, THREE
于 2016-03-13T05:40:13.213 に答える
7

@IRus の答えは正しいですが、リフレクションを使用する必要はありません。列挙型クラスごとに、values()メソッドがコンパイラによって自動的に生成されます。このメソッドは、すべてのエントリを含む配列を返します。次のように、拡張関数をこの配列で直接操作することができます。

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

そして、次のように呼び出します。

fun main(args: Array<String>) {
    Test.values().join()
}
于 2016-03-15T16:10:09.500 に答える
5

ワイルドカードを使用して、結合を次のように少し書き直します。

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

次に、 MyStringEnum が次のように定義されていると仮定します。

enum class MyStringEnum { FOO, BAR, BAZ }

次のように呼び出すことができます。

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

出力「FOO、BAR、BAZ」を取得する

クラスで結合を定義しているので、それを呼び出す実際のクラス オブジェクトが必要です。列挙型クラスは明らかにそのようには機能しませんが、その定義された列挙型はクラス with を生成できjavaClassます。したがって、これは私が思いつくことができる最高のものであり、あなたの要求の一般的な精神を満たしていると思います. このようなすべての列挙型クラスに対してやろうとしていることを達成するためのよりエレガントな方法があるかどうかはわかりません。

編集:これを使用して、これをもう少し締めることができます:

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

次のように呼び出すことができます。

println(MyStringEnum.values()[0].join())
于 2016-03-13T05:18:39.503 に答える