我是Swift的新手,我正在探索如果在使用Range迭代它时修改集合会发生什么。我无法弄清楚为什么这两个循环有不同的行为:
var things = ["a", "b", "c"]
for i in 0..<things.count {
print("i: \(i) count: \(things.count) value: \(things[i])")
if i == 1 {
things.append("x")
}
}
// i: 0 count: 3 value: a
// i: 1 count: 3 value: b
// i: 2 count: 4 value: c
VS
var things = ["a", "b", "c"]
for i in things.startIndex...things.endIndex {
print("i: \(i) count: \(things.count) value: \(things[i])")
if i == 1 {
things.append("x")
}
}
// i: 0 count: 3 value: a
// i: 1 count: 3 value: b
// i: 2 count: 4 value: c
// i: 3 count: 4 value: x
我创建了这个Array类扩展,所以我可以看到Range文字何时访问数组的属性:
extension Array {
var myCount: Int {
print("myCount (\(self.count))")
return self.count
}
var myStartIndex: Int {
print("myStartIndex (\(self.startIndex))")
return self.startIndex
}
var myEndIndex: Int {
print("myEndIndex (\(self.endIndex))")
return self.endIndex
}
}
如果我使用这些属性而不是正常属性,我会得到:
myCount (3)
i: 0 count: 3 value: a
i: 1 count: 3 value: b
i: 2 count: 4 value: c
和
myStartIndex (0)
myEndIndex (3)
i: 0 count: 3 value: a
i: 1 count: 3 value: b
i: 2 count: 4 value: c
i: 3 count: 4 value: x
我一定错过了什么,因为这感觉就像魔术!似乎endIndex
正在重新评估,但count
不是。是什么给了什么?
答案 0 :(得分:2)
这是因为在第一段代码中,您使用了半开放范围运算符(..<
),而在第二段代码中使用了正常范围运算符( ...
)。 他们是不同的。来自apple docs:
半开范围运算符
(a..<b)
定义了从a到b的范围,但不包括b。
因此,如果for
为4,则第一段代码中的things.count
循环不会继续,因为当与半开放范围运算符一起使用时,范围(0 - 4)仅在{ {1}}为0,1,2或3。
如果您使用i
代替...
,则第一段代码的结果将与第二段相同。