You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin是否支持宏?如何优化重复的SharedPreferences属性代码?

Kotlin是否支持宏?

Kotlin不支持卫生宏(hygienic macros),官方没有内置这类宏系统。不过针对你代码里重复的属性读写逻辑,Kotlin有更符合惯用风格的解决方案——委托属性(Delegated Properties),这是处理这类重复逻辑的首选方式。

解决重复代码的具体实现

你可以把SharedPreferences的读写逻辑统一抽离成自定义委托类,彻底消除代码重复:

1. 定义字符串类型的委托类

class SharedPrefStringDelegate(
    private val preferences: SharedPreferences,
    private val key: String,
    private val defaultValue: String = ""
) {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return preferences.getString(key, defaultValue).toString()
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        // 用apply()替代commit(),异步提交更高效
        preferences.edit().putString(key, value).apply()
    }
}

2. 简化JiraCredentials类

用by关键字将属性委托给上面的类,代码瞬间简洁:

class JiraCredentials(applicationContext: Context) {
    private val preferences = applicationContext.getSharedPreferences(
        "jira",
        ComponentActivity.MODE_PRIVATE
    )

    var username by SharedPrefStringDelegate(preferences, "username")
    var password by SharedPrefStringDelegate(preferences, "password")
}

扩展:支持多类型的泛型委托

如果后续需要处理Int、Boolean等其他类型的SharedPreferences属性,可以把委托类改成泛型,进一步提升复用性:

class SharedPrefDelegate<T>(
    private val preferences: SharedPreferences,
    private val key: String,
    private val defaultValue: T,
    private val getter: SharedPreferences.(String, T) -> T?,
    private val putter: SharedPreferences.Editor.(String, T) -> SharedPreferences.Editor
) {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
        return preferences.getter(key, defaultValue) ?: defaultValue
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        preferences.edit().putter(key, value).apply()
    }
}

// 封装不同类型的委托创建函数
fun SharedPreferences.stringDelegate(key: String, defaultValue: String = "") =
    SharedPrefDelegate(this, key, defaultValue, SharedPreferences::getString, SharedPreferences.Editor::putString)

fun SharedPreferences.intDelegate(key: String, defaultValue: Int = 0) =
    SharedPrefDelegate(this, key, defaultValue, SharedPreferences::getInt, SharedPreferences.Editor::putInt)

// 使用示例
class JiraCredentials(applicationContext: Context) {
    private val preferences = applicationContext.getSharedPreferences(
        "jira",
        ComponentActivity.MODE_PRIVATE
    )

    var username by preferences.stringDelegate("username")
    var password by preferences.stringDelegate("password")
    var rememberMe by preferences.intDelegate("remember_me", 0)
}

为什么不用宏?

Kotlin设计上更倾向于用语言特性(如委托、高阶函数、扩展)解决代码复用问题,这些方式比宏更具可读性和类型安全性,也更贴合Kotlin“简洁且安全”的设计理念。

内容的提问来源于stack exchange,提问作者ceving

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 21:50:37