我有一个类,每次设置时都会将用户写入SharedPreferences:
https
问题:如果用户设置在init块中,它会调用setter并将我们刚刚从共享prefs ...获得的用户写入共享的prefs。
问题1:如何直接从init块设置属性?
问题2:为什么我在定义自定义设置器时必须初始化用户,但在使用默认设置器时可以省略初始化?
答案 0 :(得分:3)
您需要使用正确的值直接初始化该属性。您可以使用stdlib中的class UserManager @Inject constructor(
val prefs: SharedPreferences,
val jsonAdapter: JsonAdapter<User>
) {
companion object {
val USER = "user"
}
var user: User = run {
val userString = prefs.getString(USER, null)
if (userString != null) {
jsonAdapter.fromJson(userString)
} else {
User()
}
}
set(value) {
field = value
prefs.edit().putString(USER, jsonAdapter.toJson(user)).apply()
}
}
函数执行此操作:
var user: User = prefs.getString(USER, null)?.let { jsonAdapter.fromJson(it) } ?: User()
set(value) {
field = value
prefs.edit().putString(USER, jsonAdapter.toJson(user)).apply()
}
Ilya Ryzhenkov在Kotlin Slack上提出的更短的语法:
Failed to connect to repository : Error performing command: C:\Program
Files\Git\bin ls-remote -h ssh://git@localhost:7999/sam/bo.git HEAD
答案 1 :(得分:2)
我认为最好的解决方案是使用&#39;支持属性&#39;这里描述的概念:https://kotlinlang.org/docs/reference/properties.html#backing-properties
private var _table: Map<String, Int>? = null
public val table: Map<String, Int>
get() {
if (_table == null)
_table = HashMap() // Type parameters are inferred
return _table ?: throw AssertionError("Set to null by another thread")
}
然后初始化构造函数中的backing属性并执行<backingproperty> = value
而不是field = value
,并将getter指向backing属性。
答案 2 :(得分:0)
看一下by map
委托,看起来这就是你想要的模式:
class User(val map: MutableMap<String, Any?>) {
var name: String by map
var age: Int by map
}
https://kotlinlang.org/docs/reference/delegated-properties.html#storing-properties-in-a-map