Swift2.1-下标脚本下标脚本
下标脚本
类,结构体和枚举可以定义下标脚本,下标脚本可以认为是访问集合(collection
),列表或序列的成员元素。你可是使用下标脚本来设置或通过索引检索值,而不需要调用实例特定的方法。例如,用下标脚本来访问一个数组(Array
)实例中的元素,可以写成这样someArray[index]
,访问字典(Dictionary
)实例中的元素可以写为someDictionary[key]
。
你可以为一个类型定义多个下标脚本,并且合适的下标脚本通过重载来使用,基于你传递的下表脚本的索引值类型。下标脚本没有限制单个纬度,并且你可以使用多个输入形参来定义下表脚本满足自定义类型的需求。
下标脚本的语法
下表脚本允许你通过在实例名后面的方括号传入一个或多个索引值对该实例进行访问和赋值。语法类似于实例方法和和计算属性的混合。写下标定义的时候要带上关键字subscript
,并且指定一个或多个输入参数和返回值类型。不像实例方法,下标脚本只能是读写或者只读的。此行为有点像点计算属性的getter和setter:
subscript(index: Int) -> Int {
get {
// return an appropriate subscript value here
}
set(newValue) {
// perform a suitable setting action here
}
}
newValue
的类型和下标脚本的返回值一样正如计算属性,你可以选择不去指定setter的(newValue
)形参。如果你没有提供一个默认形参,那么你可以调用newValue
。
与只读计算属性一样,你可以给下标脚本使用get
关键字:
subscipt(index: Int) -> {
// return an appropriate subscript value here
}
下面是下标脚本的只读属性实现的过程的,定义了一个TimeTable
来代表整数的n倍:
struct TimeTable {
let multiplier: Int
subscript(index: Int) -> Int {
return multiplier * index
}
}
let threeTimesTable = TimesTable(multiplier: 3)
print("six times three is (threeTimesTable[6])")
// prints "six times three is 18"
在这个?中,创建了一个新的TimeTable
实例来表示索引值的3倍。数值3
作为结构体构造函数入参初始化实例成员multiplier
。
你可以通过下标脚本来得到结果,比如threeTimesTable[6]
。这条语句访问了threeTimesTable
的第六个元素,返回6
的3
倍即18
。
注意
TimesTable
例子是基于一个固定的数学公式。它并不适合对threeTimesTable[someIndex]
进行赋值操作,这也是为什么附属脚本只定义为只读的原因。
下标脚本用法
"下标脚本"确切的意思取决于它使用的上下文。通常下标脚本是用来访问集合(collection
),列表(list
)或序列(sequence
)中元素的快捷方式。你可以在你自己特定的类或结构体中自由实现下标脚本来提供合适的功能。
例如,Swift的字典(Dictionary
)类型实现了通过下标脚本来对其实例中存放的值进行存取操作。在下标脚本中使用和字典索引相同类型的值,并且把一个字典值类型的值赋值给这个下标脚本来为字典设值:
var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
numberOfLegs["bird"] = 2
上面的?定义了一个名为numberOfLegs
的变量并用一个字典字面量初始化出了包含三对键值的字典实例。numberOfLegs
的字典存放值类型推断为[String:Int]
。字典实例创建完成之后通过下标脚本的方式将整型值2
赋值到字典实例的索引为bird
的位置中。
更多关于字典(Dictionary
)下标脚本的信息请参考读取和修改字典。
注意 Swift中字典的附属脚本实现中,在
get
部分返回值是Int?
,上例中的numberOfLegs
字典通过附属脚本返回的是一个Int?
或者说“可选的int
”,不是每个字典的索引都能得到一个整型值,对于没有设过值的索引的访问返回的结果就是nil
;同样想要从字典实例中删除某个索引下的值也只需要给这个索引赋值为nil
即可。
下标脚本选项
下标脚本允许任意数量的输入形参索引,并且这些输入形参可以是任何类型。下标脚本也可以返回任何类型。下标脚本可以使用变量参数和可变参数,但是不能使用输入输出(in-out
)参数或提供默认的参数值。
一个类或结构体可以根据自身需要提供多个下标脚本实现,在定义下标脚本时通过传入参数的类型进行区分,使用下标脚本时会自动匹配合适的下标脚本实现运行,这就是下标脚本的重载。
一个下标脚本参数是最常见的情况,但只要有合适的场景也可以定义多个下标脚本参数。如下例定义了一个Matrix结构体,将呈现一个Double类型的二维矩阵。Matrix结构体的下标脚本需要两个整型参数:
struct Martix {
let rows: Int, columns: Int
var grid: [Double]
init(rows: Int, columns: Int) {
self.rows = rows
self.columns = columns
grid = Array(count: rows * cloumns, repeatedValue: 0.0)
}
func indexIsValidForRow(row: Int, column: Int) -> Bool {
return row >= 0 && row < rows && cloumn >= 0 && cloumn < cloumns
}
subscript(row: Int, column: Int) -> Double {
get {
assert(indexIsValidForRow(row, cloumn: column), "index out of range")
return grid[(row * columns) + column]
}
set {
assert(indexIsValidForRow(row, column: column), "Index out of range")
grid[(row * columns) + column] = newValue
}
}
}
Matrix
提供了一个有两个形参的构造方法,分别是rows
和columns
,创建了一个足够容纳rows * columns
个数的Double
类型数组。通过传入数组长度和初始值0。0
到数组的一个构造器,将Matrix
中每个元素初始值0。0
。关于数组的构造方法和析构方法请参考创建一个空数组。
你可以通过传入合适的row
和column
的数量来构造一个新的Matrix
实例:
var matrix = Matrix(rows: 2, columns: 2)
上例中创建了一个新的两行两列的Matrix
实例。在阅读顺序从左上到右下的Matrix
实例中的数组实例grid
是矩阵二维数组的扁平化存储:
grid
将值赋给带有row
和column
下标脚本的matrix
实例表达式可以完成赋值操作,下标脚本入参使用逗号分割:
matrix[0, 1] = 1.5
matrix[1, 0] = 3.2
上面两条语句分别让matrix的右上值为 1.5,坐下值为 3.2:
Matrix
下标脚本的getter
和setter
中同时调用了下标脚本入参的row
和column
是否有效的判断。为了方便进行断言,Matrix
包含了一个名为indexIsValidForRow(_:column:)
的成员方法,用来确认入参的row
或column
值是否会造成数组越界:
func indexIsValidForRow(row: Int, column: Int) -> Bool {
return row >= 0 && row < rows && column >= 0 && column < columns
}
断言在下标脚本越界时触发:
let someValue = matrix[2, 2]
// this triggers an assert, because [2, 2] is outside of the matrix bounds
- 网络测试,带宽测试,流量测试
- github极简指南
- 设计模式学习--面向对象的5条设计原则之单一职责原则--SRP
- Spring RestFul Example (实例参考)
- C#基础知识回顾---你不知道的Lazy<T>
- 用python编写验证码
- WPF备忘录(6)WPF实现打印功能
- 适合开发者的深度学习:第一天就能使用的编码神经网络工具
- Shell 历史记录异地留痕审计与监控
- Oracle 12c: arraysize会影响结果集么?
- 【学术】实践教程:使用神经网络对犬种进行分类
- Spring Data Redis
- 使用线程新建WPF窗体(公用进度条窗体)
- Spring Data MongoDB
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- LinkedList - 61. Rotate List
- LinkedList - 143. Reorder List
- LinkedList - 160. Intersection of Two Linked Lists
- LinkedList - 21. Merge Two Sorted Lists
- LinkedList - 82. Remove Duplicates from Sorted List II
- LinkedList - 203. Remove Linked List Elements
- LinkedList - 83. Remove Duplicates from Sorted List
- LinkedList - 19. Remove Nth Node From End of List
- LinkedList - 92. Reverse Linked List II
- LinkedList - 328. Odd Even Linked List
- LinkedList - 25. Reverse Nodes in k-Group
- LinkedList - 24. Swap Nodes in Pairs
- LinkedList - 141. Linked List Cycle
- LinkedList - 206. Reverse Linked List
- Array - 188. Best Time to Buy and Sell Stock IV