- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我喜欢这种 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)(如 observable
和 vetoable
以上)示例:
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/
我正在尝试创建可选数组,但我希望仅在将元素附加到之前进行初始化。 所以我写道: var names: [String]? { willSet { if
您好,我有一个使用 willset 功能的可选变量。由于它是可选的,因此常规集将不起作用。在 will set 中,如果新值为 nil,我将变量设置为至少对其进行初始化。不幸的是,之后的值(value
我在 Swift 2 中有一个奇怪的情况,在某些情况下,当我引用一个属性时,该属性的 set 观察者被调用。 以下代码示例说明了这个问题: var i = 0 protocol PropertyPro
所以我正在学习 swift2 并且正在使用 friend 的项目。他有一个游戏计数器,但我想在用户死亡时创建一个标签。我尝试将分数标签设置为 (score),但代码将分数设置为 0,并且没有机会 sc
这个问题在这里已经有了答案: Change the value that is being set in variable's willSet block (3 个答案) 关闭 4 年前。 对于存储
这个问题在这里已经有了答案: What is the purpose of willSet and didSet in Swift? (11 个答案) 关闭 5 年前。 我是编程新手,我很难理解这两
我正在使用 xCode 9.2、Swift 4.1 鉴于这两个过度简化的类,目前有效: class Prop : Codable { var origin:String? var re
我想通过使用 didSet/willSet API 观察类中几个属性的变化。但是我想保持我的属性声明部分干净,所以我想有单独的函数来实现这个逻辑。 现在我有这样的东西: var myProperty:
逻辑是当一个数组有指定数量的元素时清除它。我可以将检查放在数组之外,但我想看看如果在数组的 willSet 事件中执行它会怎样。结果是 Array 中的元素保持静止。 这是代码 var MyArr=[
我正在尝试创建一个 UIView 子类。在初始化中,我设置了我希望子类拥有的最小和最大 y 轴原点值。该 View 将通过用户手势或动画以编程方式上下移动。我希望我可以为此使用 willSet 属性用
这个问题已经有答案了: What is the purpose of willSet and didSet in Swift? (11 个回答) 已关闭 6 年前。 我了解如何使用didSet和wil
您好,我写的是关于 https://appventure.me/2015/10/17/advanced-practical-enum-examples/#sec-4-2 的帖子 如何在属性的 didS
如何找出元组的哪个变量在 willSet/didSet 被更新? var myTuple: (a: Int, b: Int) { didSet { // Which one was
每当我设置一个 Realm 对象的属性时,我想触发代表我远程后端上的对象的另一个对象的更改。 我想知道这是否仍然是推荐的最佳实践: https://github.com/realm/realm-coc
如果我有一个 Collection View 委托(delegate)助手类,其属性如下所示: weak var delegate: UICollectionViewDelegate? { w
我在编辑器中收到一个奇怪的警告,我需要帮助来理解它想要什么 Attempting to store to property 'someProperty' within its own willSet,
如果我将属性值设置为与当前设置相同的值,会调用 willSet 和 didSet 吗?当您在这些功能中出现副作用时,了解这一点很重要。 最佳答案 是的,即使设置为相同的值,willSet 和 didS
我试图在设置之前对正在设置的数组进行排序,但 willSet 的参数是不可变的,sort 会改变值。我怎样才能克服这个限制? var files:[File]! = [File]() { wi
我想做的是在一个对象被替换为我的服务对象的委托(delegate)时通知它。我想知道是否有一种方法可以创建 willSet 的默认提示,这样我就不必为我创建的每个服务对象重复代码: protocol
我熟悉属性观察者的含义以及如何使用它。但是,我真正不明白的是何时使用它们中的每一个。在我看来这无关紧要..如果我使用 didset,我可以使用属性本身来使用 oldValue 或新值。如果我使用 wi
我是一名优秀的程序员,十分优秀!