12.5 使用下标

还记得数组和字典吗?下面的示例代码我们曾在第8章中使用过。

  1. var studentList: String[] = ["张三","李四","王五"]
  2. studentList[0] = "诸葛亮"
  3. var studentDictionary = [102 : "张三",105 : "李四", 109 : "王五"]
  4. studentDictionary[110] = "董六"

在访问数组和字典的时候,可以采用下标访问。其中数组的下标是整数类型索引,字典的下标是它的“键”。

12.5.1 下标概念

在Swift中,我们可以定义一些集合类型,它们可能会有一些集合类型的存储属性,这些属性中的元素可以通过下标访问。Swift中的下标相当于Java中的索引属性和C#中的索引器。

下标访问的语法格式如下:

  1. 面向对象类型 类型名 {
  2. 其他属性
  3. ......
  4. subscript(参数: 参数数据类型) -> 返回值数据类型 {
  5. get {
  6. return 返回值
  7. }
  8. set(新属性值) {
  9. ......
  10. }
  11. }
  12. }

上述定义中,第①行的“面向对象类型”包括类、结构体和枚举3种。第③~⑦行代码定义了下标,下标采用subscript关键字声明。下标也有类似于计算属性的getter和setter访问器。

第③~④行代码是getter访问器,getter访问器其实是一个方法,在最后使用return语句将计算结果返回。

第⑤~⑥行代码是setter访问器,其中第⑤行代码“新属性值”是要赋值给属性值。参数的声明可以省略,系统会分配一个默认的参数newValue

12.5.2 示例:二维数组

在Swift中没有提供二维数组,只有一维数组Array。我们可以自定义一个二维数组类型,然后通过两个下标参数访问它的元素,形式上类似于C语言的二维数组。

采用下标的二维数组示例代码如下:

  1. struct DoubleDimensionalArray {
  2. let rows: Int, columns: Int
  3. var grid: [Int]
  4. init(rows: Int, columns: Int) {
  5. self.rows = rows
  6. self.columns = columns
  7. grid = Array(count: rows columns, repeatedValue: 0)
  8. }
  9. subscript(row: Int, col: Int) -> Int {
  10. get {
  11. return grid[(row columns) + col]
  12. }
  13. set (newValue1){
  14. grid[(row columns) + col] = newValue1
  15. }
  16. }
  17. }
  18. var ary2 = DoubleDimensionalArray(rows: 10, columns: 10)
  19. //初始化二维数组
  20. for var i = 0; i < 10; i++ {
  21. for var j = 0; j < 10; j++ {
  22. ary2[i,j] = i j
  23. }
  24. }
  25. //打印输出二维数组
  26. for var i = 0; i < 10; i++ {
  27. for var j = 0; j < 10; j++ {
  28. print("\t \(ary2[i,j])")
  29. }
  30. print("\n")
  31. }

上述代码第①行定义了二维数组结构体DoubleDimensionalArray,第②行代码声明了存储属性rowscolumns,分别使用了存储二维数组的最大行数和最大列数。第③行代码是声明构造器,它使用了初始化实例。有关构造器的详细内容请参见第14章。第④行代码grid = Array(count: rows * columns, repeatedValue: 0)是初始化存储属性gridgrid是一维数组,二维数组中的数据事实上保存在grid属性中。repeatedValue参数表示数组中所有元素全部赋值为0。

第⑤行代码定义下标,其中的参数有两个。第⑥行代码是getter访问器返回,数据是从一维数组grid返回的,(row * columns) + col是它的下标表达式。第⑦行代码是setter访问器返回,把一个新值参数newValue1赋值给一维数组grid,它的下标表达式也是(row * columns) + col。注意新值参数的声明可以省略,使用系统提供的newValue参数,setter访问器可以修改为如下形式:

  1. set{
  2. grid[(row * columns) + col] = newValue
  3. }

第⑧行代码是创建并初始化10×10大小的二维数组。访问二维数组使用第⑨行代码ary2[i,j]属性。最后输出结果如下:

  1. 0 0 0 0 0 0 0 0 0 0
  2. 0 1 2 3 4 5 6 7 8 9
  3. 0 2 4 6 8 10 12 14 16 18
  4. 0 3 6 9 12 15 18 21 24 27
  5. 0 4 8 12 16 20 24 28 32 36
  6. 0 5 10 15 20 25 30 35 40 45
  7. 0 6 12 18 24 30 36 42 48 54
  8. 0 7 14 21 28 35 42 49 56 63
  9. 0 8 16 24 32 40 48 56 64 72
  10. 0 9 18 27 36 45 54 63 72 81

这两个双循环非常影响性能。我们可以通过Playground的时间轴查看它的运行情况,如图12-2所示。

{%}

图 12-2 Playground时间轴

下标参数的个数是没有限制的,可以有多个,但是访问的时候会很麻烦,因此尽量少用。