下标语法在数组中追加值

时间:2015-06-13 23:20:41

标签: arrays swift syntax

在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"]

我认为我们不允许使用下标语法将新项目附加到数组的末尾,但这似乎是语言中的漏洞。有人可以向我解释为什么会发生这种情况和/或这是一个有效的行为还是一个错误?谢谢!

2 个答案:

答案 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?

此外,每当您为阵列分配内容时,都必须进行检查,这将非常慢。