gpt4 book ai didi

properties - Kotlin 中是否有 didSet/willSet 模拟?

转载 作者:IT老高 更新时间:2023-10-28 13:27:12 25 4
gpt4 key购买 nike

我喜欢这种 Swift 语法;它对很多事情都非常有帮助:

var foo: Bar = Bar() {
willSet {
baz.prepareToDoTheThing()
}
didSet {
baz.doTheThing()
}
}

我很想在 Kotlin 中做到这一点。但是,I can't find the proper syntax !

Kotlin 中有这样的东西吗?

var foo: Bar = Bar()
willSet() {
baz.prepareToDoTheThing()
}
didSet() {
baz.doTheThing()
}

最佳答案

虽然 Kotlin 没有为属性变化观察提供内置的 Swift 风格的解决方案,但您仍然可以根据您的目标以多种方式进行。

  • observable(...) 代表(in stdlib)这允许您处理属性更改。使用示例:

    var foo: String by Delegates.observable("bar") { property, old, new ->
    println("$property has changed from $old to $new")
    }

    这里,"bar"是属性 foo 的初始值,并且每次赋值后都会调用lambda,让你观察变化。还有 vetoable(...) delegate这可以让您阻止更改。

  • 您可以使用custom setter用于在实际值更改之前/之后执行任意代码的属性:

    var foo: String = "foo"
    set(value: String) {
    baz.prepareToDoTheThing()
    field = value
    baz.doTheThing()
    }

    作为 @KirillRakhman请注意,此解决方案非常有效,因为它不会在方法调用和对象中引入任何开销,尽管在多个属性的情况下代码会有些重复。

  • 一般来说,你可以实现自己的property delegate ,在 getValue(...) 中明确提供属性行为和 setValue(...)功能。

    为了简化您的任务,请使用 ObservableProperty<T> 抽象类,允许您实现观察属性变化的委托(delegate)(如 observablevetoable 以上)示例:

    var foo: String by object : ObservableProperty<String>("bar") {
    override fun beforeChange(property: KProperty<*>, oldValue: String, newValue: String): Boolean {
    baz.prepareToDoTheThing()
    return true // return false if you don't want the change
    }

    override fun afterChange(property: KProperty<*>, oldValue: String, newValue: String) {
    baz.doTheThing()
    }
    }

    为方便起见,您可以编写一个创建委托(delegate)对象的函数:

    fun <T> observing(initialValue: T,
    willSet: () -> Unit = { },
    didSet: () -> Unit = { }
    ) = object : ObservableProperty<T>(initialValue) {
    override fun beforeChange(property: KProperty<*>, oldValue: T, newValue: T): Boolean =
    true.apply { willSet() }

    override fun afterChange(property: KProperty<*>, oldValue: T, newValue: T) = didSet()
    }

    然后你只需将 lambdas 作为 willSet 传递给它和 didSet ( the default argument 对他们来说是 { } )。用法:

    var foo: String by observing("bar", willSet = {
    baz.prepareToDoTheThing()
    }, didSet = {
    baz.doTheThing()
    })

    var baq: String by observing("bar", didSet = { println(baq) })

在任何情况下,您都需要确保观察更改的代码不会再次设置属性,因为它可能会陷入无限递归,否则您可以在观察代码中检查 setter 是否为递归调用。

关于properties - Kotlin 中是否有 didSet/willSet 模拟?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39842261/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com