Охрана в Свифте дает другой ответ, если - PullRequest
0 голосов
/ 08 ноября 2018

В очень простой программе для сравнения двух связанных списков у меня есть рекурсивная функция, которая проверяет, совпадает ли текущий узел обоих списков, и затем перемещается к следующему узлу.

Базовый случай, если два узла равны нулю, мы выходим.

Так что код с if / else

есть:

func compareLL(llistOne: SinglyLinkedListNode?, llistTwo: SinglyLinkedListNode?) -> Bool {
    if (llistOne == nil && llistTwo == nil) { return true }
    if (llistOne?.data == llistTwo?.data) {return compareLL(llistOne: llistOne?.next, llistTwo: llistTwo?.next)}
    return false
}

с охраной

func compareLL(llistOne: SinglyLinkedListNode?, llistTwo: SinglyLinkedListNode?) -> Bool {
    guard (llistOne != nil && llistTwo != nil) else {return true}
    if (llistOne?.data == llistTwo?.data) {return compareLL(llistOne: llistOne?.next, llistTwo: llistTwo?.next)}
    return false
}

Так почему же они дают разные результаты?

То есть, сравнивая два разных связанных списка (разной длины) - поэтому мы возвращаем true при llistOne = 5 и list 2 = nil в соответствии с оператором guard (и это не относится к оператору if then else). Это неожиданно, так как я думал, что они должны получить тот же результат.

Как мне разработать защитное выражение, чтобы оно выглядело так же, как и шаблон if?

1 Ответ

0 голосов
/ 08 ноября 2018

Отрицание llistOne == nil && llistTwo == nil равно llistOne != nil || llistTwo != nil.

Ваш if возвращается, только если оба значения равны нулю. Но ваш guard в настоящее время возвращается, если один или оба равны нулю. Это не то же самое.

Поэтому измените guard на:

guard (llistOne != nil || llistTwo != nil) else {return true}

Возможно, вы захотите прочитать законы де Моргана .

Основное краткое изложение законов де Моргана для логической логики:

not(a and b) === not(a) or not(b)
not(a or b) === not(a) and not(b)

В вашем случае a - это llistOne == nil, а b - llistTwo == nil.

У вас было a and b (llistOne == nil && llistTwo == nil). Итак, not(a and b) - это not(a) or not(b) (llistOne != nil || llistTwo != nil)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...