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
相关产品推荐
相关产品推荐

