Подтвердить что ты не робот

Котлин - когда выражение с возвращаемым типом функции

Я хочу использовать kotlin, когда выражения и общие методы упрощают общие настройки api для Android.

Вместо того, чтобы постоянно обращаться к 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
    }

Конечно, это не сработает. Но существует ли какое-либо решение для использования выражения для возвращаемого типа функции? Все предложения приветствуются.

4b9b3361

Ответ 1

Чтобы достичь именно того, что вы хотите, вы можете использовать параметры типа 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?

Если вы создаете 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