Kotlin - 当表达式具有返回类型的函数时

Kru*_*hah 10 generics android types function kotlin

我希望利用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
    }
Run Code Online (Sandbox Code Playgroud)

当然,它不会起作用.但是当表达式为函数的返回类型时,是否有任何解决方案?欢迎所有建议.

hot*_*key 9

要完全达到您的要求,您可以使用reified类型参数.这将使编译器在其调用站点内联您的函数,并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?
Run Code Online (Sandbox Code Playgroud)

如果你创建get了一个operator函数,你也可以使用运算符语法来调用它: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
Run Code Online (Sandbox Code Playgroud)