我的以下代码是简化应用程序属性的方法:

class Preference<T>(private val key: String, private val defaultValue: T) : ReadWriteProperty<AppPreferences, T> {

    override fun getValue(thisRef: AppPreferences, property: KProperty<*>): T {
        @Suppress("UNCHECKED_CAST")
        return ((properties.getProperty(key) ?: defaultValue) as T)
    }

    override fun setValue(thisRef: AppPreferences, property: KProperty<*>, value: T) {
        properties.setProperty(key, value.toString())
        saveProperties()
    }
}
//endregion

//region Variables
var isAuthenticationEnabled by Preference("is_authentication_needed", false)
var timeoutSeconds by Preference("timeout_seconds", 1000)
var adminKey by Preference("admin_key", "")
//endregion

但我需要一种方法来转换属性,它总是作为字符串读取到T.这种方法不起作用的原因很明显,但任何try 转换,例如与When(T)或其他将导致错误"不能使用‘T’作为具体化的类型参数.改用一个类". 所以我的问题是:如何在getValue方法中将该字符串转换为T?

谢谢

推荐答案

让创建Preference的人告诉您如何将T转换为String或从String转换为T.添加(T) -> String(String) -> T作为构造函数参数.

class Preference<T>(
    private val key: String,
    private val defaultValue: T,
    private val convertToString: (T) -> String,
    private val convertFromString: (String) -> T
) : ReadWriteProperty<AppPreferences, T> {

    override fun getValue(thisRef: AppPreferences, property: KProperty<*>): T {
        return convertFromString(properties.getProperty(key)) ?: defaultValue
    }

    override fun setValue(thisRef: AppPreferences, property: KProperty<*>, value: T) {
        properties.setProperty(key, convertToString(value))
        saveProperties()
    }
}

然后,您可以为特定类型的首选项创建函数--StringIntBoolean等.这些方法将创建Preference的实例,并传入(T) -> String(String) -> T参数,然后返回该实例.

fun preference(key: String, defaultValue: String) = Preference(
    key, defaultValue, { it }, { it }
)

fun preference(key: String, defaultValue: Int) = Preference(
    key, defaultValue, Int::toString, String::toInt
)

fun preference(key: String, defaultValue: Boolean) = Preference(
    key, defaultValue, Boolean::toString, String::toBoolean
)

Kotlin相关问答推荐

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

Kotlin 海峡没有结束

如果启用了Flyway迁移,则不能具有配置属性';datources.default.架构-生成

处理合成层次 struct 中的深层按钮以切换视图

在Kotlin lambda的参数中如何指定函数类型?

有什么方法可以要求在 kotlin 中的类型参数上进行注释?

如何避免键盘打开时jetpack compose 内容上升

Kotlin 中的as Long和.toLong()有什么区别?

通过顺序多米诺骨牌操作列表管理对象的最佳方法是什么?

如何从 kotlin 中的数据类访问 val?

奇怪的 cotlin check Not Null 参数错误

Kotlin:查找集合中最常见的元素

是否可以通过超时暂停协程?

具有多个不同类型来源的 LiveData

有没有办法重用 Job 实例?

Android Kotlin StringRes 数量String

Kotlin DataBinding 将静态函数传递到布局 xml

如果我可以将 Flow 和 StateFlow 与生命周期范围 \ viewLifecycleOwner.lifecycleScope 一起使用,那么在 ViewModel 中使用 LiveData 有什么意义

重复构建失败To use Coroutine features, you must add `ktx`......

将字符串编码为Kotlin中的UTF-8