web-dev-qa-db-ja.com

Kotlin-具現化された型パラメーターとして「T」を使用できません。代わりにクラスを使用してください

このようなSharedPreferencesから値を取得する単純なヘルパー関数があります。

operator inline fun <reified T : Any> SharedPreferences.get(key: String, defaultValue: T? = null): T? {
    return when (T::class) {
        String::class -> getString(key, defaultValue as? String) as T?
        Int::class -> getInt(key, defaultValue as? Int ?: -1) as T?
        Boolean::class -> getBoolean(key, defaultValue as? Boolean ?: false) as T?
        Float::class -> getFloat(key, defaultValue as? Float ?: -1f) as T?
        Long::class -> getLong(key, defaultValue as? Long ?: -1) as T?
        else -> throw UnsupportedOperationException("Not yet implemented")
    }
}

具象化された型パラメーターを使用してクラス型を切り替えましたが、これは演算子関数なので、以下のような角括弧構文で呼び出すことができるはずです。

val name: String? = prefs[Constants.PREF_NAME]

ただし、呼び出すたびに、関数がクラス型を取得できないことを示すUnsupportedOperationExceptionがスローされます。

デバッガを接続してT::classを評価すると、エラー"Cannot use 'T' as reified type parameter. Use a class instead."が発生します

私の機能の何が問題になっていますか?間違いを見つけられなかった。誰か助けてもらえますか?

編集:クラス全体は here および this is where ですエラーが発生します。

更新:Kotlinコンパイラの問題のようです。トラック https://youtrack.jetbrains.com/issue/KT-17748 および https://youtrack.jetbrains.com/issue/KT-17748 で更新します。

8
Krupal Shah

問題は奇妙ですが、Int::classInt?::classと同じではないようです(これはいずれにしても違法な表現です)。

行を追加すると、次のようになります。

println(T::class)

getメソッドに対してval age: Int? = prefs["AGE", 23]を呼び出すと、Java.lang.Integerが出力されることがわかります。

Int?Java.lang.Integerに翻訳されているようです。

可能な(しかし、私見のようなハックな)ソリューションは、Javaクラスへの参照を次の場合のケースとして使用することです。

operator inline fun <reified T : Any> get(key: String, defaultValue: T? = null): T? {
    return when (T::class) {
        String::class -> getString(key, defaultValue as? String) as T?
        Java.lang.Integer::class -> getInt(key, defaultValue as? Int ?: -1) as T?
        Java.lang.Boolean::class -> getBoolean(key, defaultValue as? Boolean ?: false) as T?
        Java.lang.Float::class -> getFloat(key, defaultValue as? Float ?: -1f) as T?
        Java.lang.Long::class -> getLong(key, defaultValue as? Long ?: -1) as T?
        else -> throw UnsupportedOperationException("Not yet implemented")
    }
}
3
Jorn Vernee