前面我们把一些非常常用的东西,以及使用的细节也说了,比如函数,方法,变量这些,都是我们经常见到的,现在让我们继续往下学习:
1.附属脚本
附属脚本可以定义在类(Class)、结构体(structure)和枚举(enumeration)这些目标中,可以认为是访问对象,集合或序列的快捷方式,不需要再调用实例的特定的赋值和访问方法.
比如,我们定义了一个数组Array,那么我们就可以用someArray[Index]这样子来取数组的元素,同样的,Dictionary也是如此,someDictionary[key],这样子我们就可以取出相应的值或者元素.
2.附属脚本的语法
附属脚本允许你通过在实例后面的方括号中传入一个或者多个的索引值来对实例进行访问和赋值,语法类似于实例方法和计算型属性的混合,比如:
subscript(Index: Int) -> Int{
get {
// 返回与入参匹配的Int类型的值
}
set(newValue) {
// 进行赋值运算
}
}
PS: subscript只能在某个类,结构体和枚举里面声明,否则的话编译器就会报错,并且如果写了newValue,那么newValue的类型必须和附属脚本定义的返回类型相同,当然,如果与计算属性相同的入参,那就可以不用写了.
这个是个完整的例子
struct TimesTable {
let multiplier: Int
subscript(index: Int) -> Int {
return multiplier * index
}
}
let threeTimesTable = TimesTable(multiplier: 3)
println("3的6倍是\(threeTimesTable[6])")
// 打印出来的结果: 3的6倍是18
3.附属脚本的用法
一般附属脚本是用来访问集合(collection),列表(list)或序列(sequence)中元素的快捷方式,我们可以在自己特定的类或结构体中自由的实现附属脚本来提供合适的功能,比如:
var numberOfLegs = ["spider": 8,"ant": 6,"cat": 4]
numberOfLegs["bird"] = 2
println(numberOfLegs)
// 打印出来的结果: [ant: 6,bird: 2,cat: 4,spider: 8]
PS: Swift 中字典的附属脚本实现中,在get部分返回值是Int?,上例中的numberOfLegs字典通过下边返回的是一个 Int?或者说“可选的 int”,不是每个字典的索引都能得到一个整型值,对于没有设过值的索引的访问返回的结果就是 nil,同样想要从字典实例中删除某个索引下的值也只需要给这个索引赋值为 nil 就可以了.
4.附属脚本选项
虽然说附属脚本是允许任意数量的入参索引,并且每个入参类型也没有限制,舒服脚本的返回值也可以是任何类型,包括变量参数和可变参数,唯一一个不允许的就是在In-Out参数或者给参数设置默认值的时候是不允许的.
一个类或结构体可以根据自身需要提供多个附属脚本实现,在定义附属脚本时通过入参个类 型进行区分,使用附属脚本时会自动匹配合适的附属脚本实现运行,这就是附属脚本的重载,比如:
struct Matrix {
let rows: Int,columns: Int
var grid: [Double]
init(rows: Int,columns: Int) {
self.rows = rows
self.columns = columns
grid = Array(count: rows * columns,repeatedValue: 0.0)
}
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,column: column),"Index out of range")
return grid[(row * columns) + column]
}
set {
assert(indexIsValidForRow(row,"Index out of range")
}
}
}
var matrix = Matrix(rows: 2,columns: 2)
let someValue = matrix[0,1]
println(someValue)
// 打印出来的结果: 0.0
PS: 由于我们在调用时,所设置的条件都是2,一旦我们超过了这个范围,就不符合我们所定义的条件,所以编译器会引起断言.
好了,这次我们就讲到这里,下次我们继续~