本頁包含內容:html
下標腳本 能夠定義在類(Class)、結構體(structure)和枚舉(enumeration)中,是訪問集合(collection),列表(list)或序列(sequence)中元素的快捷方式。可使用下標腳本的索引設置和獲取值,不須要再調用對應的存取方法。舉例來講,用下標腳本訪問一個Array
實例中的元素能夠寫做someArray[index]
,訪問Dictionary
實例中的元素能夠寫做someDictionary[key]
。ios
一個類型能夠定義多個下標腳本,經過不一樣索引類型進行重載。下標腳本不限於一維,你能夠定義具備多個入參的下標腳本知足自定義類型的需求。swift
下標腳本容許你經過在實例名稱後面的方括號中傳入一個或者多個索引值來對實例進行存取。語法相似於實例方法語法和計算型屬性語法的混合。與定義實例方法相似,定義下標腳本使用subscript
關鍵字,指定一個或多個入參和返回類型。與實例方法不一樣的是,下標腳本能夠設定爲讀寫或只讀。這種行爲由 getter 和 setter 實現,有點相似計算型屬性:數組
subscript(index: Int) -> Int { get { // 返回一個適當的 Int 類型的值 } set(newValue) { // 執行適當的賦值操做 } }
newValue
的類型和下標腳本的返回類型相同。如同計算型屬性,能夠不指定 setter 的參數(newValue
)。若是不指定參數,setter 會提供一個名爲newValue
的默認參數。app
如同只讀計算型屬性,能夠省略只讀下標腳本的get
關鍵字:ide
subscript(index: Int) -> Int { // 返回一個適當的 Int 類型的值 }
下面代碼演示了只讀下標腳本的實現,這裏定義了一個TimesTable
結構體,用來表示傳入整數的乘法表:函數
struct TimesTable { let multiplier: Int subscript(index: Int) -> Int { return multiplier * index } } let threeTimesTable = TimesTable(multiplier: 3) print("six times three is \(threeTimesTable[6])") // 輸出 "six times three is 18"
在上例中,建立了一個TimesTable
實例,用來表示整數3
的乘法表。數值3
被傳遞給結構體的構造函數,做爲實例成員multiplier
的值。ui
你能夠經過下標腳本訪問threeTimesTable
實例,例如上面演示的threeTimesTable[6]
。這條語句查詢了3
的乘法表中的第六個元素,返回3
的6
倍即18
。spa
注意
TimesTable
例子基於一個固定的數學公式,對threeTimesTable[someIndex]
進行賦值操做並不合適,所以下標腳本定義爲只讀的。 code
下標腳本的確切含義取決於使用場景。下標腳本一般做爲訪問集合(collection),列表(list)或序列(sequence)中元素的快捷方式。你能夠針對本身特定的類或結構體的功能來自由地以最恰當的方式實現下標腳本。
例如,Swift 的Dictionary
類型實現下標腳本用於對其實例中儲存的值進行存取操做。爲字典設值時,在下標腳本中使用和字典的鍵類型相同的鍵,並把一個和字典的值類型相同的值賦給這個下標腳本:
var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4] numberOfLegs["bird"] = 2
上例定義一個名爲numberOfLegs
的變量,並用一個包含三對鍵值的字典字面量初始化它。numberOfLegs
字典的類型被推斷爲[String: Int]
。字典建立完成後,該例子經過下標腳本將String
類型的鍵bird
和Int
類型的值2
添加到字典中。
更多關於Dictionary
下標腳本的信息請參考讀取和修改字典
注意
Swift 的Dictionary
類型的下標腳本接受並返回可選類型的值。上例中的numberOfLegs
字典經過下標腳本返回的是一個Int?
或者說「可選的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(count: rows * columns, repeatedValue: 0.0) } func indexIsValidForRow(row: Int, column: Int) -> Bool { return row >= 0 && row < rows && column >= 0 && column < columns } subscript(row: Int, column: Int) -> Double { get { assert(indexIsValidForRow(row, column: 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
到數組的構造器,將矩陣中每一個位置的值初始化爲0.0
。關於數組的這種構造方法請參考建立一個空數組。
你能夠經過傳入合適的row
和column
的數量來構造一個新的Matrix
實例:
var matrix = Matrix(rows: 2, columns: 2)
上例中建立了一個Matrix
實例來表示兩行兩列的矩陣。該Matrix
實例的grid
數組按照從左上到右下的閱讀順序將矩陣扁平化存儲:
將row
和column
的值傳入下標腳原本爲矩陣設值,下標腳本的入參使用逗號分隔:
matrix[0, 1] = 1.5 matrix[1, 0] = 3.2
上面兩條語句分別調用下標腳本的 setter 將矩陣右上角位置(即row
爲0
、column
爲1
的位置)的值設置爲1.5
,將矩陣左下角位置(即row
爲1
、column
爲0
的位置)的值設置爲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] // 斷言將會觸發,由於 [2, 2] 已經超過了 matrix 的範圍