XOR в Swift 5? - PullRequest
       36

XOR в Swift 5?

2 голосов
/ 02 апреля 2019

Я пытаюсь выполнить операцию XOR в Swift 5. В документации, по-видимому, не упоминается явное выполнение этого с двумя логическими значениями:

https://docs.swift.org/swift-book/LanguageGuide/AdvancedOperators.html

Возможно ли это?В нем говорится об использовании операции ^, но я получаю сообщение об ошибке при попытке:

 card != nil ^ appointment.instructor == nil

ОШИБКА Смежные операторы находятся в неассоциативной группе приоритетов 'ComparisonPrecedence'

Ответы [ 3 ]

5 голосов
/ 02 апреля 2019

Вам необходимо определить ^ для Bool, поскольку оно существует только для Ints. Смотрите яблочную документацию здесь .

Пример:

import UIKit
import PlaygroundSupport

extension Bool {
    static func ^ (left: Bool, right: Bool) -> Bool {
        return left != right
    }
}

let a = true
let b = false
print (a^b)
4 голосов
/ 02 апреля 2019

Оператор ^ определен для целочисленных типов, но не для Bool. Вы можете добавить свое собственное определение, но оно не является строго необходимым. Операция XOR на Bool такая же, как операция !=. Вот таблицы истинности для A XOR B и A != B:

A B A^B A!=B
F F  F   F
F T  T   T
T F  T   T
T T  F   F

Итак, мы могли бы написать ваше выражение так:

(card != nil) != (appointment.instructor == nil)

Это довольно трудно понять, хотя. Если цель состоит в том, чтобы убедиться, что точно один из случаев верен, я мог бы написать это для ясности:

[(card != nil), (appointment.instructor == nil)].filter({ $0 == true }).count == 1
2 голосов
/ 02 апреля 2019

В документации четко указано, что ^ является побитовым оператором XOR и, поскольку Bool является только одним битом, битовый XOR для него не определен. Если вы поместите правильные скобки в ваше выражение, вы получите правильное сообщение об ошибке:

(card != nil) ^ (appointment.instructor == nil)

Двоичный оператор '^' нельзя применять к двум операндам Bool

В Swift нет оператора XOR, поэтому чтобы выполнить XOR на двух Bool с, вам нужно определить собственную функцию или оператор XOR.

infix operator ^^
extension Bool {
    static func ^^(lhs:Bool, rhs:Bool) -> Bool {
        if (lhs && !rhs) || (!lhs && rhs) {
            return true
        }
        return false
    }
}

Тесты:

let trueValue:Bool? = true
let falseValue:Bool? = false
let nilValue:Bool? = nil

(trueValue != nil) ^^ (nilValue != nil) // true
(trueValue != nil) ^^ (falseValue != nil) // false
(nilValue != nil) ^^ (nilValue != nil) // false
...