【发布时间】:2022-01-02 09:44:21
【问题描述】:
我正在尝试构建一个类,其中某些值是可观察但也可序列化的。
这显然有效并且序列化有效,但是必须为每个字段添加一个 setter 并且必须在每个 setter 中手动调用 change(...),这非常繁琐:
interface Observable {
fun change(message: String) {
println("changing $message")
}
}
@Serializable
class BlahVO : Observable {
var value2: String = ""
set(value) {
field = value
change("value2")
}
fun toJson(): String {
return Json.encodeToString(serializer(), this)
}
}
println(BlahVO().apply { value2 = "test2" })
正确输出
changing value2
{"value2":"test2"}
我尝试过介绍代表:
interface Observable {
fun change(message: String) {
println("changing $message")
}
@Suppress("ClassName")
class default<T>(defaultValue: T) {
private var value: T = defaultValue
operator fun getValue(observable: Observable, property: KProperty<*>): T {
return value
}
operator fun setValue(observable: Observable, property: KProperty<*>, value: T) {
this.value = value
observable.change(property.name)
}
}
}
@Serializable
class BlahVO : Observable {
var value1: String by Observable.default("value1")
fun toJson(): String {
return Json.encodeToString(serializer(), this)
}
}
println(BlahVO().apply { value1 = "test1" }) 正确触发更改检测,但它不序列化:
changing value1
{}
如果我从 Observable 转到 ReadWriteProperty,
interface Observable {
fun change(message: String) {
println("changing $message")
}
fun <T> look(defaultValue: T): ReadWriteProperty<Observable, T> {
return OP(defaultValue, this)
}
class OP<T>(defaultValue: T, val observable: Observable) : ObservableProperty<T>(defaultValue) {
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
super.setValue(thisRef, property, value)
observable.change("blah!")
}
}
}
@Serializable
class BlahVO : Observable {
var value3: String by this.look("value3")
fun toJson(): String {
return Json.encodeToString(serializer(), this)
}
}
结果是一样的:
changing blah!
{}
Delegates.vetoable 也是如此
var value4: String by Delegates.vetoable("value4", {
property: KProperty<*>, oldstring: String, newString: String ->
this.change(property.name)
true
})
输出:
changing value4
{}
代表似乎不适用于 Kotlin 序列化
还有哪些其他选项可以在不破坏其序列化的情况下观察属性的变化,而这些选项也适用于其他平台(KotlinJS、KotlinJVM、Android...)?
【问题讨论】:
-
您的一个示例是使用 Delegates.vetoable,但您是否尝试过 Delegates.observable?
-
vetoable 和 observable 做同样的事情,我已经对其进行了测试以确认。 Vetoable 只是可观察的,返回 true / false 以查看它是否可以应用更改。此外,我添加的 ReadWriteProperty 示例实际上是一个 Observable。如果我想使用 Delegates,我需要对 Serializer 进行更改
标签: kotlin serialization kotlin-multiplatform kotlin-delegate