【问题标题】:Is there a standard assignment operator syntax for assigning a value only if it's different?是否有标准的赋值运算符语法仅在值不同时才分配值?
【发布时间】:2018-09-12 17:09:32
【问题描述】:

例如a =! bif a != b then { a = b }

在 Swift 中,即使设置了相同的值,也会设置属性。由于我使用的是领域通知,因此我不想设置属性,除非它不同。我可以做一堆 IF THEN 语句,但我宁愿创建自己的赋值运算符来使用。

编辑

我想我的问题是双重的,因为 inout 似乎会触发 willSet/didSet 块。

1) 我的主要问题'是否有标准的赋值运算符语法仅在值不同时才分配值?没有回答

2) Swift 中有没有一种方法可以在不触发willSet/didSet 的情况下创建此运算符?重点是不触发领域通知。

【问题讨论】:

  • 如果相同,为什么不直接覆盖它呢?不是每次取值不一样都要多加一个操作吗?
  • 这个操作符是你创建的=! 还是你要求的替代方法
  • @Carpsen90 我确实创建了 =!,但我对这种情况是否有标准语法感兴趣。如果 a == b 已经存在,则不应触发 willSet/didSet
  • AFAIK 唯一不触发属性观察者的方法是 if 条件,

标签: swift operators variable-assignment


【解决方案1】:

您可以为此使用关键路径,因为关键路径不需要 inout 声明。

infix operator =!: AssignmentPrecedence

func =!<T, U: Equatable>(lhs: (T, ReferenceWritableKeyPath<T,U>), rhs: U) {
    if lhs.0[keyPath: lhs.1] != rhs {
       lhs.0[keyPath: lhs.1] = rhs
    }
}

func >><T, U: Equatable>(lhs: T, rhs: ReferenceWritableKeyPath<T,U>) -> (T, ReferenceWritableKeyPath<T,U>) {
    return (lhs, rhs)
}

上面的代码创建了您在问题中描述的运算符,并且还重载了 &gt;&gt; 一个以创建 Object+KeyPath 对以将其传递给 =!

用法大致如下:

class Person {
    var age: Int = 0 {
        didSet {
            print("New age:", age)
        }
    }
}

let person = Person()
person>>\.age =! 4
person>>\.age =! 4
person>>\.age =! 4
person>>\.age =! 5
person>>\.age =! 5

代码将按预期打印:

New age: 4
New age: 5

,即使同一个值被多次连续赋值。

【讨论】:

  • 感谢您的回答!我不确定我是否会使用它,因为 `>>` 要求会降低代码的可读性。我现在可能无法使用 If Then 语句。你在这里有很多经验。你知道为什么我最初的问题甚至没有得到回答和否决吗?
  • @TomDaniel 是的,使用两个运算符会影响代码的可读性和可理解性,可能这可以简化为一个运算符,但我怀疑结果会更具可读性。关于对您的问题的否决,不确定投票者的原因,也许他/她对问题的第一个修订版投了反对票,这有点短。
猜你喜欢
  • 2016-09-28
  • 2020-08-10
  • 2020-08-17
  • 2014-05-04
  • 1970-01-01
  • 2020-01-10
相关资源
最近更新 更多