忽略setter并直接设置属性

时间:2016-03-19 23:02:37

标签: kotlin

我有一个类,每次设置时都会将用户写入SharedPreferences:

https

问题:如果用户设置在init块中,它会调用setter并将我们刚刚从共享prefs ...获得的用户写入共享的prefs。

问题1:如何直接从init块设置属性?

问题2:为什么我在定义自定义设置器时必须初始化用户,但在使用默认设置器时可以省略初始化?

3 个答案:

答案 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