在访问Array或Dictionary时,我们除了可以通过系统的标准函数库,还可以使用下面的方式:
array[index]
-
dictionary[index]
上面的方式称为 下标,可用于类、结果体或枚举。
下标语法
在下标方式中,我们可以在实例名称后的中括号中,通过一个或多个索引值来对实例进行存取(有点类似实例方法语法和计算型属性语法的混合)。具体的语法如下,
subscript(index:Int) ->Int
{
get
{
//执行读取操作
}
set(newValue)
{
//执行赋值操作
}
}
说明:
1.我们可以通过
getter
或setter
方法,来设置下标的读写权限。(在这里可以复习一下之前的计算型属性)
2.newValue
的类型和读取操作中的返回类型相同,如果我们不设置newValue
参数名,系统会提供一个默认的newValue
参数名。
请看下面的使用例子
struct TestStruct
{
let testValue:Int
subscript(index:Int) ->Int
{
get{return testValue * 6}
}
}
let indexx = TestStruct.init(testValue: 6)
let indexxx = indexx[3]
print("\(indexx)--\(indexxx)")
输出结果
TestStruct(testValue: 6)--18
Program ended with exit code: 0
说明
- 我们定义了一个名称为
TestStruct
的结构体,用来表示所传入整数的乘法表。它的下标定义为只读的。 -
TestStruct.init(testValue: 6)
表示整数6
的乘法表 - 我们可以通过下标来访问结构体,即
indexx[3]
它访问的是所传入整数乘法表的第3
个元素,结果等于18
下标用法
请看下面的例子
var testDict = ["string01":1,"string02":3,"string03":5];
testDict["string04"] = 7
print("\(testDict)")
print("\(String(describing: testDict["string02"]))")
输出结果
["string03": 5, "string01": 1, "string02": 3, "string04": 7]
Optional(3)
Program ended with exit code: 0
如上,我们声明了一个字典testDict
,初始值为["string01":1,"string02":3,"string03":5]
,z,然后通过下标的方式,添加一个新的键值对"string04":7
,同时我们通过下标来访问键"string02"
所对应的值(Int?
类型).
注意
Swift
的Dictionary
类型的下标接受并返回可选类型的值。上例中的testDict
字典通过下标返回的是一个Int?
或者说“可选的int”
。Dictionary
类型之所以如此实现下标,是因为不是每个键都有个对应的值,同时 这也提供了一种通过键删除对应值的方式,只需将键对应的值赋值为nil
即可。
下标选项
- 下标可以接受任意数量的入参,这些入参可以是任意类型,同时返回值也可以是任意类型的。下标可以使用变量参数和可变参数,但是不能使用输入输出参数,也不能给参数设置默认值。
- 一个类或结构体可以根据自身需要提供多个下标实现,使用下标时将通过入参的数量和类型进行区分,自动匹配
合适的下标,这就是下标的重载。
请看下面的例子
struct Matrix
{
let rows:Int
let columns:Int
var gird:[Double]
init(rows:Int,columns:Int)
{
self.rows = rows
self.columns = columns
self.gird = Array.init(repeating: 0.0, count: rows * columns)
}
func indexIsValidForRow(row:Int,column:Int) -> Bool
{
return row >= 0 && row < rows && column >= 0 && column < columns
}
subscript(row:Int,column:Int) ->Double
{
get
{
assert(indexIsValidForRow(row: row, column: column), "Index out of range")
return gird[(row * column) + column]
}
set
{
assert(indexIsValidForRow(row: row, column: column), "Index out of range")
gird[(row * column) + column] = newValue
}
}
}
var matrix = Matrix.init(rows: 3, columns: 3)
//设置值
matrix[0,2] = 5.5
matrix[1,2] = 6.6
//访问值
print("\(matrix[0,2])")
print("\(matrix[1,2])")
输出结果
5.5
6.6
Program ended with exit code: 0
如上,我们定义了一个矩阵结构体Matrix
,
-
Matrix
提供了一个接受两个入参的构造方法,入参分别是rows
和columns
,创建了一个足够容纳
rows * columns
个Double
类型的值的数组。通过传入数组长度和初始值0.0
到数组的构造器,将矩阵中每个位置的值初始化 为0.0
。 - 通过
var matrix = Matrix.init(rows: 3, columns: 3)
,我们创建了一个3*3
的实例matrix
- 通过下标的方式,如
matrix[0,2] = 5.5
来给矩阵的某一个位置设置值,同时也能通过该方式来读取矩阵某一位置的值 -
indexIsValidForRow
用来检查我们设置值或者取值时传入的位置(row,columns
)是否在矩阵范围内。当不在矩阵范围内时,断言也会被触发。