★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝()➤GitHub地址:➤原文地址: ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★类,结构和枚举可以定义下标,下标是用于访问集合,列表或序列的成员元素的快捷方式。您可以使用下标按索引设置和检索值,而无需单独的设置和检索方法。例如,您可以访问在元素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
如果您没有自己提供,则会为您的setter提供一个默认参数。
与只读计算属性一样,您可以通过删除get
关键字及其大括号来简化只读下标的声明:
- subscript(index: Int) -> Int {
- // Return an appropriate subscript value here.
- }
这是一个只读下标实现的示例,它定义了一个TimesTable
表示n次整数表的结构:
- struct TimesTable {
- 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"
在此示例中,TimesTable
创建了一个新实例来表示三次表。这通过将值的值传递3
给结构initializer
作为实例multiplier
参数的值来表示。
您可以threeTimesTable
通过调用其下标来查询实例,如调用中所示threeTimesTable[6]
。这将请求三次表中的第六个条目,该表返回值18
或3
次6
。
注意
一个ñ -times表是基于一个固定的数学规则。设置threeTimesTable[someIndex]
为新值是不合适的,因此下标for TimesTable
被定义为只读下标。
下标用法
“下标”的确切含义取决于使用它的上下文。下标通常用作访问集合,列表或序列中的成员元素的快捷方式。您可以以最合适的方式为您的特定类或结构的功能实现下标。
例如,Swift的Dictionary
类型实现了一个下标来设置和检索存储在Dictionary
实例中的值。您可以通过在下标括号中提供字典的键类型的键,并将字典的值类型的值分配给下标来设置字典中的值:
- var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
- numberOfLegs["bird"] = 2
上面的示例定义了一个名为的变量numberOfLegs
,并使用包含三个键值对的字典文字对其进行初始化。numberOfLegs
推断字典的类型是。创建字典后,此示例使用下标分配向字典添加键和值。[String: Int]
String
"bird"
Int
2
有关Dictionary
下标的详细信息,请参阅。
注意
Swift的Dictionary
类型将其键值下标实现为获取并返回可选类型的下标。对于numberOfLegs
上面的字典,键值下标采用并返回type的值Int?
,或“optional int”。该Dictionary
类型使用可选的下标类型来模拟不是每个键都有值的事实,并通过为该键赋值来为删除键的值提供一种方法nil
。
下标选项
下标可以采用任意数量的输入参数,这些输入参数可以是任何类型。下标也可以返回任何类型。下标可以使用可变参数并提供默认参数值,但它们不能使用输入输出参数。
类或结构可以根据需要提供尽可能多的下标实现,并且将基于在使用下标的点处的下标括号内包含的值或值的类型来推断要使用的适当下标。多个下标的这种定义称为下标重载。
虽然下标采用单个参数是最常见的,但如果适合您的类型,也可以定义带有多个参数的下标。以下示例定义了一个Matrix
结构,该结构表示Double
值的二维矩阵。该Matrix
结构的标有两个整型参数:
- struct Matrix {
- let rows: Int, columns: Int
- var grid: [Double]
- init(rows: Int, columns: Int) {
- self.rows = rows
- self.columns = columns
- grid = Array(repeating: 0.0, count: rows * columns)
- }
- func indexIsValid(row: Int, column: Int) -> Bool {
- return row >= 0 && row < rows && column >= 0 && column < columns
- }
- subscript(row: Int, column: Int) -> Double {
- get {
- assert(indexIsValid(row: row, column: column), "Index out of range")
- return grid[(row * columns) + column]
- }
- set {
- assert(indexIsValid(row: row, column: column), "Index out of range")
- grid[(row * columns) + column] = newValue
- }
- }
- }
Matrix
提供了采用两个参数称为初始值rows
和columns
,并创建一个数组,它是大到足以存储类型的值。矩阵中的每个位置都给出初始值。为此,将数组的大小和初始单元格值传递给数组初始值设定项,该数组初始值设定项创建并初始化正确大小的新数组。在中更详细地描述了此初始化程序。rows * columns
Double
0.0
0.0
您可以Matrix
通过将适当的行和列计数传递给其初始值设定项来构造新实例:
- var matrix = Matrix(rows: 2, columns: 2)
上面的示例创建了一个Matrix
包含两行和两列的新实例。grid
此Matrix
实例的数组实际上是矩阵的扁平版本,从左上角到右下角读取:
可以通过将行和列值传递到下标中来设置矩阵中的值,用逗号分隔:
- matrix[0, 1] = 1.5
- matrix[1, 0] = 3.2
这两个语句调用下标的setter来设置1.5
矩阵右上角的位置(其中row
是0
和column
是1
),并3.2
在左下角位置(其中row
是1
和column
是0
):
该Matrix
标的getter和setter都包含一个断言,以检查标的row
和column
值是有效的。为了协助这些断言,Matrix
包括被称为一个方便的方法indexIsValid(row:column:)
,检查是否所请求的row
和column
是矩阵的边界内:
- func indexIsValid(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.
输入下标
如上所述,实例下标是您在特定类型的实例上调用的下标。您还可以定义在类型本身上调用的下标。这种下标称为类型下标。您可以通过在static
关键字之前写入关键字来指明类型下标subscript
。类可以使用class
关键字,以允许子类覆盖超类的该下标的实现。下面的示例显示了如何定义和调用类型下标:
- enum Planet: Int {
- case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
- static subscript(n: Int) -> Planet {
- return Planet(rawValue: n)!
- }
- }
- let mars = Planet[4]
- print(mars)