我有一个简单的辅助函数来从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")
}
}
我使用了reified类型参数来切换类类型,因为它是一个操作符函数,我应该能够使用如下方括号语法调用:
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更新。
答案 0 :(得分:3)
这个问题很奇怪,但似乎Int::class
与Int?::class
不同(任何方式都是非法表达)。
添加以下行时:
println(T::class)
使用get
方法,并致电val age: Int? = prefs["AGE", 23]
,您会看到它打印java.lang.Integer
。
似乎Int?
已翻译为java.lang.Integer
。
一种可能的(但是有点hacky)解决方案是使用对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")
}
}