Существует ли стандартный синтаксис оператора присваивания для присвоения значения, только если оно отличается? - PullRequest
0 голосов
/ 12 сентября 2018

Например, a =! b - это if a != b then { a = b }

. В Swift свойство устанавливается, даже если оно задает то же значение.Поскольку я использую уведомления области, я не хочу устанавливать свойство, если оно не отличается.Я могу сделать кучу операторов IF THEN, но я бы предпочел просто создать свой собственный оператор присваивания для использования.

EDIT

Полагаю, мой вопрос теперь двоякий, чтопохоже, что inout вызовет willSet/didSet блоков.

1) Мой главный вопрос: «Существует ли стандартный синтаксис оператора присваивания для присвоения значения, только если оно отличается?»не ответили

2) Есть ли способ в Swift создать этот оператор без вызова willSet/didSet?Весь смысл в том, чтобы Уведомление о Царстве не сработало.

1 Ответ

0 голосов
/ 12 сентября 2018

Вы можете использовать ключевые пути для этого, поскольку ключевые пути не требуют 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)
}

Приведенный выше код создает оператор, который вы описали в вопросе, а также перегружает оператор >>, чтобы создать пару 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

, даже если одно и то же значение было присвоено несколько раз подряд.

...