Swift中的后卫对if给出了不同的答案

时间:2018-11-08 04:02:42

标签: swift

在一个非常简单的比较两个链表的程序中,我有一个递归函数,用于测试两个链表的当前节点是否相同,然后移至下一个节点。

基本情况是,如果两个节点均为零,我们退出。

因此,如果使用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
}

那么为什么它们会产生不同的结果?

也就是说,比较两个不同的链表(不同的长度)-因此,根据保护声明,当llistOne = 5list 2 = nil时,我们返回true(这不适用于if then else语句) 。这是出乎意料的,因为我认为他们应该获得相同的结果。

如何开发一个与if模式相同的保护声明?

1 个答案:

答案 0 :(得分:4)

llistOne == nil && llistTwo == nil的取反是llistOne != nil || llistTwo != nil

仅当两个值均为零时,您的if才返回。但是您的guard当前返回(如果其中一个或两个均为零)。不一样。

因此将您的guard更改为:

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

您可能希望阅读De Morgan's Laws

De Morgan的布尔逻辑定律的基本摘要是:

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

在您的情况下,allistOne == nil,而bllistTwo == nil

您有a and bllistOne == nil && llistTwo == nil)。所以not(a and b)not(a) or not(b)llistOne != nil || llistTwo != nil