import Foundation
//***********************************************************************************************
//1.Subscripts(附属脚本)
//_______________________________________________________________________________________________
//介绍
//附属脚本可以定义在类,结构体和枚举这些目标中,可以认为是访问对象,集合或者序列的快捷方式,不需要再调用实例的特定的赋值和访问方法
//举例来说,用附属脚本访问一个数组实例中的元素可以这样写 someArray[index],访问字典实例中的元素可以这样写 someDictionary[key]
//对于同一个目标可以定义多个附属脚本,通过索引值类型的不同来进行重载,而且索引值的个数可以是多个
//***********************************************************************************************
//2.Subscript Syntax(附属脚本语法)
//_______________________________________________________________________________________________
//介绍
//附属脚本允许你通过在实例后面的方括号中传入一个或者多个索引值来对实例进行访问和赋值。语法类似于实例方法和计算型属性的混合。与定义实例方法类似,定义附属脚本使用 subscript 关键字,显式声明入参(一个或者多个)和返回类型。与实例方法不同的是附属脚本可以只设置为读写或者只读,这种方式又有点像属性的 getter 和 setter
//_______________________________________________________________________________________________
//代码演示附属脚本语法结构
/*
subscript(index: Int) -> Int{ //因为 subscript 不能单独列出,所以代码进行注释
get{
//返回与入参匹配的 Int 类型的值
}
set(newValue){ //newValue 类型必须和附属脚本定义的返回类型相同
//执行赋值操作
}
}
*/
//_______________________________________________________________________________________________
//代码演示在 TimesTable 结构体中使用只读附属脚本的用法(和只读计算型属性相同)
struct TimesTable{
let multiplier: Int
subscript(index: Int) -> Int{
return multiplier * index
}
}
let threeTimesTable = TimesTable(multiplier: 3)
println("3 的 6 倍是 \(threeTimesTable[6])") //通过附属脚本访问形式访问数据
//***********************************************************************************************
//3.Subscript Usage(附属脚本用法)
//_______________________________________________________________________________________________
//介绍
//根据使用场景的不同附属脚本也有不同的含义,通常附属脚本是用来访问集合,列表,序列中的快捷方式
//_______________________________________________________________________________________________
//实例代码演示
var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
numberOfLegs["bird"] = 2
println(numberOfLegs) //Swift 的字典(Dictionary)实现了通过附属脚本来对其实例中存放的值进行存取操作。在附属脚本中使用和字典索引相同类型的值,并且把一个字典值类型的值赋值给这个附属脚 本来为字典设值
//***********************************************************************************************
//4.Subscript Options(附属脚本选项)
//_______________________________________________________________________________________________
//介绍
//附属脚本允许任意数量的入参索引,并且每个入参类型也没有限制。附属脚本的返回值也可以是任何类型。附属脚本可以使用变量参数和可变参数,但使用写入读出(in-out)参数或 给参数设置默认值都是不允许的
//一个类或结构体可以根据自身需要提供多个附属脚本实现,在定义附属脚本时通过入参个类 型进行区分,使用附属脚本时会自动匹配合适的附属脚本实现运行,这就是附属脚本的重载
//_______________________________________________________________________________________________
//实例代码演示
struct Matrix{ //Matrix 提供了一个两个入参的构造方法,入参分别是 rows 和 columns,创建了一个足够容 纳 rows * columns 个数的 Double 类型数组
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 indexIsValidForRaw(row: Int, column: Int) -> Bool{ //判断数组是否越界进行断言操作
return row >= 0 && row < rows && column < columns
}
subscript(row: Int, column: Int) -> Double{ //使用附属脚本格式语法设置入参
get{
assert(indexIsValidForRaw(row, column: column), "Index out of range") //设置断言检测数组是否越界
return grid[(row * columns) + column]
}
set{
assert(indexIsValidForRaw(row, column: column), "Index out of range")
grid[(row * columns) + column] = newValue
}
}
}
var matrix = Matrix(rows: 2, columns: 2)
println(matrix.grid)
println(matrix[0, 1]) //通过附属脚本对应的访问形式访问数据
matrix[0, 1] = 1.5 //通过附属脚本对应的设置形式设置数据
println(matrix[0, 1])