12.5 使用下标
还记得数组和字典吗?下面的示例代码我们曾在第8章中使用过。
var studentList: String[] = ["张三","李四","王五"]
studentList[0] = "诸葛亮"
var studentDictionary = [102 : "张三",105 : "李四", 109 : "王五"]
studentDictionary[110] = "董六"
在访问数组和字典的时候,可以采用下标访问。其中数组的下标是整数类型索引,字典的下标是它的“键”。
12.5.1 下标概念
在Swift中,我们可以定义一些集合类型,它们可能会有一些集合类型的存储属性,这些属性中的元素可以通过下标访问。Swift中的下标相当于Java中的索引属性和C#中的索引器。
下标访问的语法格式如下:
面向对象类型 类型名 { ①
其他属性
......
subscript(参数: 参数数据类型) -> 返回值数据类型 { ②
get { ③
return 返回值
} ④
set(新属性值) { ⑤
......
} ⑥
} ⑦
}
上述定义中,第①行的“面向对象类型”包括类、结构体和枚举3种。第③~⑦行代码定义了下标,下标采用subscript
关键字声明。下标也有类似于计算属性的getter和setter访问器。
第③~④行代码是getter访问器,getter访问器其实是一个方法,在最后使用return
语句将计算结果返回。
第⑤~⑥行代码是setter访问器,其中第⑤行代码“新属性值”是要赋值给属性值。参数的声明可以省略,系统会分配一个默认的参数newValue
。
12.5.2 示例:二维数组
在Swift中没有提供二维数组,只有一维数组Array
。我们可以自定义一个二维数组类型,然后通过两个下标参数访问它的元素,形式上类似于C语言的二维数组。
采用下标的二维数组示例代码如下:
struct DoubleDimensionalArray { ①
let rows: Int, columns: Int ②
var grid: [Int]
init(rows: Int, columns: Int) { ③
self.rows = rows
self.columns = columns
grid = Array(count: rows columns, repeatedValue: 0) ④
}
subscript(row: Int, col: Int) -> Int { ⑤
get {
return grid[(row columns) + col] ⑥
}
set (newValue1){
grid[(row columns) + col] = newValue1 ⑦
}
}
}
var ary2 = DoubleDimensionalArray(rows: 10, columns: 10) ⑧
//初始化二维数组
for var i = 0; i < 10; i++ {
for var j = 0; j < 10; j++ {
ary2[i,j] = i j ⑨
}
}
//打印输出二维数组
for var i = 0; i < 10; i++ {
for var j = 0; j < 10; j++ {
print("\t \(ary2[i,j])")
}
print("\n")
}
上述代码第①行定义了二维数组结构体DoubleDimensionalArray
,第②行代码声明了存储属性rows
和columns
,分别使用了存储二维数组的最大行数和最大列数。第③行代码是声明构造器,它使用了初始化实例。有关构造器的详细内容请参见第14章。第④行代码grid = Array(count: rows * columns, repeatedValue: 0)
是初始化存储属性grid
,grid
是一维数组,二维数组中的数据事实上保存在grid
属性中。repeatedValue
参数表示数组中所有元素全部赋值为0。
第⑤行代码定义下标,其中的参数有两个。第⑥行代码是getter访问器返回,数据是从一维数组grid
返回的,(row * columns) + col
是它的下标表达式。第⑦行代码是setter访问器返回,把一个新值参数newValue1
赋值给一维数组grid
,它的下标表达式也是(row * columns) + col
。注意新值参数的声明可以省略,使用系统提供的newValue
参数,setter访问器可以修改为如下形式:
set{
grid[(row * columns) + col] = newValue
}
第⑧行代码是创建并初始化10×10大小的二维数组。访问二维数组使用第⑨行代码ary2[i,j]
属性。最后输出结果如下:
0 0 0 0 0 0 0 0 0 0
0 1 2 3 4 5 6 7 8 9
0 2 4 6 8 10 12 14 16 18
0 3 6 9 12 15 18 21 24 27
0 4 8 12 16 20 24 28 32 36
0 5 10 15 20 25 30 35 40 45
0 6 12 18 24 30 36 42 48 54
0 7 14 21 28 35 42 49 56 63
0 8 16 24 32 40 48 56 64 72
0 9 18 27 36 45 54 63 72 81
这两个双循环非常影响性能。我们可以通过Playground
的时间轴查看它的运行情况,如图12-2所示。
图 12-2 Playground时间轴
下标参数的个数是没有限制的,可以有多个,但是访问的时候会很麻烦,因此尽量少用。