我想利用kotlin的when表达式和通用方法来简化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
    }

Of Course, it will not work. But is there any solution to use when expression for return type of a function? All suggestions are welcome.

推荐答案

To achieve exactly what you want, you can use reified type parameters. This will make the compiler inline your function at its call sites with T replaced with the type used at the call site.

The function would look like:

@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?

If you make get an operator function, you can also call it using the operator syntax: prefs[name].

The calls should, of course, provide enough type information for the compiler to infer 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

Kotlin相关问答推荐

我可以检测一个函数是否在Kotlin中被递归调用(即,重入)吗?

外键是主键的一部分,但不是索引的一部分.房间

Kotlin协程挂起继续线程

Kotlin编译器如何决定是否可以在任何给定点调用Suspend方法?

Gradle:无法创建 ExtensiblePolymorphicDomainObjectContainer

如何在 Kotlin 中为类方法调用传递变量

为什么 Kotlin 在 sumOf 函数 lambda 中默认不将数字视为Int?

使用空键映射获取

为什么 KFunction2 在 Kotlin 中不是可表示类型?

Kotlin 日期格式从一种更改为另一种

runBlocking 中的 deferred.await() 抛出的异常即使在被捕获后也被视为未处理

如何使用 gradle 脚本 Kotlin 构建文件构建可运行的 ShadowJar?

从代码块执行和返回(在 Elvis 运算符之后)

如何将命令行参数传递给Gradle Kotlin DSL

Kotlin:如何修改成对的值?

如何将 CameraView 与 Jetpack Compose 一起使用?

Android:Exoplayer - ExtractorMediaSource 已弃用

@StringRes、@DrawableRes、@LayoutRes等android注释使用kotlin参数进行判断

在Kotlin中创建通用二维数组

如何在 Fragment 中使用 Anko DSL?