private var oneAndOnly {
get {
let faceCardIndices = cards.indices.filter({cards[$0].isFaceUp})
return faceCardIndices.count == 1 ? faceCardIndices.first : nil
}
}
与
private var oneAndOnly {
get {
return cards.indices.filter({cards[$0].isFaceUp}).first
}
}
如果.first
在没有元素的情况下返回 nil,我会假设它们是等效的,但它们不是。第一个块实际上给了我一个新的索引,因为第二个块被卡住了。
不同之处在于,只有当正好有一张这样的牌时,第一个块才会找到翻转卡片的索引。
第二个块将返回翻转的第一张卡的索引,即使有多个这样的卡。
换句话说:
faceCardIndices = [5]
这两种方法都将返回5
但用于:
faceCardIndices = [1, 5]
第一个将返回nil
,而第二个将返回1
。
在所有其他方面,这些方法是等效的。
在这一行:
return faceCardIndices.count == 1 ? faceCardIndices.first : nil
如果faceCardIndices.count
不等于1
,那么faceCardIndices.first
甚至不会被评估......它只是返回nil
.
使用您的其他代码:
return cards.indices.filter({cards[$0].isFaceUp}).first
它会尝试得到.first
,无论.filter
的结果如何......这可能导致尝试获取零元素的第一个元素。
当cards
是一个空数组时,它们似乎是等效的函数,两个函数都返回nil
。
在游乐场:
struct Card {
var isFaceUp: Bool
}
struct Test {
var cards = [Card]()
var oneAndOnly: Int? {
get {
let faceCardIndices = cards.indices.filter({cards[$0].isFaceUp})
return faceCardIndices.count == 1 ? faceCardIndices.first : nil
}
}
var oneAndOnly2: Int? {
get {
return cards.indices.filter({cards[$0].isFaceUp}).first
}
}
}
var test = Test()
test.oneAndOnly //nil
test.oneAndOnly2 //nil
此外,当cards
包含 4 张卡片时,一张牌朝上,两个函数返回相同的2
索引。
var test = Test()
test.cards.append(Card(isFaceUp: false))
test.cards.append(Card(isFaceUp: false))
test.cards.append(Card(isFaceUp: true))
test.cards.append(Card(isFaceUp: false))
test.oneAndOnly //2
test.oneAndOnly2 //2
当数组包含 1 个以上的面朝上卡时,差异就会发挥作用,第一个函数返回nil
第二个函数返回第一个面朝上卡的索引。这是由于仅在第一个函数中使用的faceCardIndices.count == 1
约束。
var test = Test()
test.cards.append(Card(isFaceUp: false))
test.cards.append(Card(isFaceUp: true))
test.cards.append(Card(isFaceUp: true))
test.cards.append(Card(isFaceUp: false))
test.oneAndOnly //nil
test.oneAndOnly2 //1