Swift5.4 语言指南(十四) 下标
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/9739175.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
类,结构和枚举可以定义下标,这些下标是访问集合,列表或序列的成员元素的快捷方式。您可以使用下标按索引设置和检索值,而无需使用单独的方法进行设置和检索。例如,您可以访问在元素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
与下标的返回值相同。与计算属性一样,您可以选择不指定设置器的(newValue)
参数。newValue
如果您自己不提供一个默认参数,它将被提供给设置器。
与只读计算属性一样,可以通过删除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
times 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
上面的字典,键值下标接受并返回typeInt?
或“ 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
,并创建一个足够大以存储type值的数组。矩阵中的每个位置的初始值都为。为此,将数组的大小和初始单元格值传递给数组初始化器,该初始化器创建并初始化一个具有正确大小的新数组。使用默认值创建数组中将详细描述此初始化程序。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)