このような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 で更新します。
問題は奇妙ですが、Int::class
はInt?::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")
}
}