在Swift编程语言书中,它明确指出:
您无法使用下标语法将新项目附加到数组的末尾
本书中提供的示例还指出,即使替换值集的长度与您要替换的范围不同,也可以。例如:
var shoppingList = ["Eggs", "Milk", "Chocolate"]
shoppingList[0...2] = ["Bananas", "Apples"]
// shoppingList = ["Bananas", "Apples"]
这是有道理的,因为您正在使用Banana和Apple的值替换3个值。但是,如果我们这样做了:
var shoppingList = ["Eggs", "Milk", "Chocolate"]
shoppingList[0...2] = ["Bananas", "Apples", "Sausage", "Pear"]
// shoppingList = ["Bananas", "Apples", "Sausage", "Pear"]
我认为我们不允许使用下标语法将新项目附加到数组的末尾,但这似乎是语言中的漏洞。有人可以向我解释为什么会发生这种情况和/或这是一个有效的行为还是一个错误?谢谢!
答案 0 :(得分:3)
当书上写着“你不能使用下标语法将新项目附加到数组的末尾”时,实际意味着“Array.subscript (index: Int) -> T
已实施的方式,你不能用它来将一个新项目附加到数组的末尾“。
subscript
对于具有属性质量的函数来说只是一些语法糖,它具有一些参数(在本例中为index
)并且获取或设置一个值(在这种情况下为T
})。但就像任何功能一样,它的功能可以是你想要的任何功能。它可以将值设置为index
,或者如果你以这种方式编写它就可以发射核导弹。
碰巧,Array
定义了subscript
的第二个重载,它对范围进行操作, 具有扩展功能。但是这本书专指的是更传统的一个只需要一个索引。
为了演示,这里是Array
的扩展,它定义了另一个下标版本,这次,如果你命名索引extend:
,它将使用新值扩展数组,直到所需的索引:
extension Array {
// add a new subscript with a named argument
subscript (extending index: Int) -> T {
get { return self[index] }
set(newValue) {
if index < self.endIndex {
self[index]
}
else {
let extendBy = index + 1 - self.endIndex
self.extend(Repeat(count: extendBy, repeatedValue: newValue))
}
}
}
}
var a = [1,2,3]
a[extending: 5] = 100
// a is now [1, 2, 3, 100, 100, 100]
答案 1 :(得分:2)
下标只不过是没有名字的函数。它可以执行任何功能 - &gt;修改是可能的。与每个功能一样,如果您传递的是无效参数,则会失败。
当使用带有array[index]
之类的数组的下标来设置新值时,数组简单地用输入替换现有值,因此如果您输入的索引尚不存在,则不能替换该值,因此将失败。
这本书指的是像
这样的东西var array = [0, 1, 2]
array[3] = 3
会出现indexOutOfBounds
错误,因为索引3尚不存在且下标不会自动添加新元素。
让我们假设这个下标的实现会检查索引是否还没有存在,并在需要时添加它。会发生什么:
var array = [0, 1, 2]
array[100] = 3 // Index 100 doesn't exist -> But what to add at index 3 to 99?
此外,每当您为阵列分配内容时,都必须进行检查,这将非常慢。