我希望利用kotlin的表达式和通用方法来简化Android的共享首选项api。
而不是调用getString()& getInt()等等,我想做的是创建一个扩展函数,它将根据函数的返回类型进行切换并调用适当的方法。如下所示:
fun <T> SharedPreferences.get(key: String): T? {
when (T) { //how do I switch on return type and call appropriate function?
is String -> getString(key, null)
is Int -> getInt(key, -1)
is Boolean -> getBoolean(key, false)
is Float -> getFloat(key, -1f)
is Long -> getLong(key, -1)
}
return null
}
当然,它不会起作用。但是当表达式为函数的返回类型时,是否有任何解决方案?欢迎提出所有建议。
答案 0 :(得分:9)
为了达到您想要的效果,您可以使用reified type parameters。这将使编译器在其呼叫站点内联您的功能,并将T
替换为呼叫站点使用的类型。
该功能如下:
@Suppress("IMPLICIT_CAST_TO_ANY")
inline operator fun <reified T> SharedPreferences.get(key: String): T? =
when (T::class) {
String::class -> getString(key, null)
Int::class -> getInt(key, -1)
Boolean::class -> getBoolean(key, false)
Float::class -> getFloat(key, -1f)
Long::class -> getLong(key, -1)
else -> null
} as T?
如果您将get
设为operator
function,您也可以使用运算符语法调用它:prefs[name]
。
当然,调用应该为编译器提供足够的类型信息来推断T
:
val i: Int? = prefs["i"] // OK, the type information is taken from the declaration
val j: Int = prefs["i"]!! // OK
val x = prefs["x"] // Error, not enough type information
val y = prefs.get<String>("y") // OK, the type will be `String?`
fun f(z: Int) = z
f(prefs["z"]!!) // OK, the type information is taken from the parameter type