Swift4.2語言規範(十四) 下標
類,結構和枚舉可以定義下標,下標是用於訪問集合,列表或序列的成員元素的快捷方式。您可以使用下標按索引設置和檢索值,而無需單獨的設置和檢索方法。例如,您可以訪問在元素Array
實例作為someArray[index]
和元素的Dictionary
實例作為someDictionary[key]
。
您可以為單個類型定義多個下標,並根據傳遞給下標的索引值的類型選擇要使用的相應下標重載。下標不限於單個維度,您可以定義具有多個輸入參數的下標以滿足您的自定義類型的需求。
下標語法
下標使您可以通過在實例名稱後面的方括號中寫入一個或多個值來查詢類型的實例。它們的語法類似於實例方法語法和計算屬性語法。使用subscript
關鍵字編寫下標定義,並以與實例方法相同的方式指定一個或多個輸入參數和返回類型。與實例方法不同,下標可以是讀寫或只讀。此行為由getter和setter以與計算屬性相同的方式傳遞:
1 subscript(index: Int) -> Int { 2 get { 3 // return an appropriate subscript value here 4 } 5 set(newValue) { 6 // perform a suitable setting action here 7 } 8}
類型newValue
與下標的返回值相同。與計算屬性一樣,您可以選擇不指定setter的(newValue)
參數。newValue
如果您自己不提供,則會向您的setter提供一個默認參數。
與只讀計算屬性一樣,您可以通過刪除get
關鍵字及其大括號來簡化只讀下標的聲明:
1 subscript(index: Int) -> Int { 2 // return an appropriate subscript value here 3 }
這是一個只讀下標實現的示例,它定義了一個TimesTable
表示n次整數表的結構:
1 struct TimesTable {2 let multiplier: Int 3 subscript(index: Int) -> Int { 4 return multiplier * index 5 } 6 } 7 let threeTimesTable = TimesTable(multiplier: 3) 8 print("six times three is \(threeTimesTable[6])") 9 // Prints "six times three is 18"
在此示例中,TimesTable
創建了一個新實例來表示三次表。這通過將值的值傳遞3
給結構initializer
作為實例multiplier
參數的值來表示。
您可以threeTimesTable
通過調用其下標來查詢實例,如調用中所示threeTimesTable[6]
。這將請求三次表中的第六個條目,該表返回值18
或3
次6
。
註意
一個n-times-table表是基於一個固定的數學規則。設置threeTimesTable[someIndex]
為新值是不合適的,因此下標for TimesTable
被定義為只讀下標。
下標用法
“下標”的確切含義取決於使用它的上下文。下標通常用作訪問集合,列表或序列中的成員元素的快捷方式。您可以以最合適的方式為您的特定類或結構的功能實現下標。
例如,Swift的Dictionary
類型實現了一個下標來設置和檢索存儲在Dictionary
實例中的值。您可以通過在下標括號中提供字典鍵類型的鍵,並將字典的值類型的值分配給下標來設置字典中的值:
1 var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4] 2 numberOfLegs["bird"] = 2
上面的示例定義了一個名為的變量numberOfLegs
,並使用包含三個鍵值對的字典文字對其進行初始化。numberOfLegs
推斷字典的類型是。創建字典後,此示例使用下標分配向字典添加鍵值和值。[String: Int]
String
"bird"
Int
2
有關Dictionary
下標的詳細信息,請參閱訪問和修改字典。
註意
Swift的Dictionary
類型將其鍵值下標實現為獲取並返回可選類型的下標。對於numberOfLegs
上面的字典,鍵值下標采用並返回type的值Int?
,或“optional int”。該Dictionary
類型使用可選的下標類型來模擬不是每個鍵都有值的事實,並通過為該鍵賦值來提供刪除nil
鍵值的方法。
下標選項
下標可以采用任意數量的輸入參數,這些輸入參數可以是任何類型。下標也可以返回任何類型。下標可以使用可變參數,但它們不能使用輸入輸出參數或提供默認參數值。
類或結構可以根據需要提供盡可能多的下標實現,並且將基於在使用下標的點處的下標括號內包含的值或值的類型來推斷要使用的適當下標。多個下標的這種定義稱為下標重載。
雖然下標采用單個參數是最常見的,但如果適合您的類型,也可以定義帶有多個參數的下標。以下示例定義了一個Matrix
結構,該結構表示Double
值的二維矩陣。該Matrix
結構的標有兩個整型參數:
1 struct Matrix { 2 let rows: Int, columns: Int 3 var grid: [Double] 4 init(rows: Int, columns: Int) { 5 self.rows = rows 6 self.columns = columns 7 grid = Array(repeating: 0.0, count: rows * columns) 8 } 9 func indexIsValid(row: Int, column: Int) -> Bool { 10 return row >= 0 && row < rows && column >= 0 && column < columns 11 } 12 subscript(row: Int, column: Int) -> Double { 13 get { 14 assert(indexIsValid(row: row, column: column), "Index out of range") 15 return grid[(row * columns) + column] 16 } 17 set { 18 assert(indexIsValid(row: row, column: column), "Index out of range") 19 grid[(row * columns) + column] = newValue 20 } 21 } 22 }
Matrix
提供了采用兩個參數稱為初始值rows
和columns
,並創建一個數組,它是大到足以存儲類型的值。矩陣中的每個位置都給出初始值。為此,將數組的大小和初始單元格值傳遞給數組初始值設定項,該數組初始值設定項創建並初始化正確大小的新數組。在使用默認值創建數組中更詳細地描述了此初始化程序。rows * columns
Double
0.0
0.0
您可以Matrix
通過將適當的行和列計數傳遞給其初始化程序來構造新實例:
1 var matrix = Matrix(rows: 2, columns: 2)
上面的示例創建了一個Matrix
包含兩行和兩列的新實例。grid
此Matrix
實例的數組實際上是矩陣的扁平版本,從左上角到右下角讀取:
可以通過將行和列值傳遞到下標中來設置矩陣中的值,用逗號分隔:
1 matrix[0, 1] = 1.5 2 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
是矩陣的邊界內:
1 func indexIsValid(row: Int, column: Int) -> Bool { 2 return row >= 0 && row < rows && column >= 0 && column < columns 3 }
如果您嘗試訪問矩陣邊界之外的下標,則會觸發斷言:
1 let someValue = matrix[2, 2] 2 // this triggers an assert, because [2, 2] is outside of the matrix bounds
Swift4.2語言規範(十四) 下標