《Swift Programming Language 》——附屬指令碼(Subscripts),swiftlanguage
附屬指令碼可以定義在類(Class)、結構體(structure)和枚舉(enumeration)這些目標中,可以認為是訪問對象、集合或序列的捷徑,不需要再調用執行個體的特定的賦值和存取方法。舉例來說,用附屬指令碼訪問一個數組(Array)執行個體中的元素可以這樣寫 someArray[index] ,訪問字典(Dictionary)執行個體中的元素可以這樣寫 someDictionary[key]。
對於同一個目標可以定義多個附屬指令碼,通過索引值類型的不同來進行重載,而且索引值的個數可以是多個。
譯者:這裡附屬指令碼重載在本小節中原文並沒有任何示範
附屬指令碼文法
附屬指令碼允許你通過在執行個體後面的方括弧中傳入一個或者多個的索引值來對執行個體進行訪問和賦值。文法類似於執行個體方法和計算型屬性的混合。與定義執行個體方法類似,定義附屬指令碼使用subscript關鍵字,顯式聲明入參(一個或多個)和傳回型別。與執行個體方法不同的是附屬指令碼可以設定為讀寫或唯讀。這種方式又有點像計算型屬性的getter和setter:
subscript(index: Int) -> Int { get { // 返回與入參匹配的Int類型的值 } set(newValue) { // 執行賦值操作 }}
newValue的類型必須和附屬指令碼定義的傳回型別相同。與計算型屬性相同的是set的入參聲明newValue就算不寫,在set代碼塊中依然可以使用預設的newValue這個變數來訪問新賦的值。
與唯讀計算型屬性一樣,可以直接將原本應該寫在get代碼塊中的代碼寫在subscript中:
subscript(index: Int) -> Int { // 返回與入參匹配的Int類型的值}
下面代碼示範了一個在TimesTable結構體中使用唯讀附屬指令碼的用法,該結構體用來展示傳入整數的n倍。
struct TimesTable { let multiplier: Int subscript(index: Int) -> Int { return multiplier * index }}let threeTimesTable =TimesTable(multiplier: 3)println("3的6倍是\(threeTimesTable[6])")// 輸出 "3的6倍是18"
在上例中,通過TimesTable結構體建立了一個用來表示索引值三倍的執行個體。數值3作為結構體建構函式入參初始化執行個體成員multiplier。
你可以通過附屬指令碼來來得到結果,比如threeTimesTable[6]。這句話訪問了threeTimesTable的第六個元素,返回18或者6的3倍。
注意:
TimesTable例子是基於一個固定的數學公式。它並不適合開放寫入權限來對threeTimesTable[someIndex]進行賦值操作,這也是為什麼附屬指令碼只定義為唯讀原因。
附屬指令碼用法
根據使用情境不同附屬指令碼也具有不同的含義。通常附屬指令碼是用來訪問集合(collection),列表(list)或序列(sequence)中元素的捷徑。你可以在你自己特定的類或結構體中自由的實現附屬指令碼來提供合適的功能。
例如,Swift 的字典(Dictionary)實現了通過附屬指令碼來對其執行個體中存放的值進行存取操作。在附屬指令碼中使用和字典索引相同類型的值,並且把一個字典值類型的值賦值給這個附屬指令碼來為字典設值:
var numberOfLegs = ["spider": 8,"ant": 6, "cat": 4]numberOfLegs["bird"] = 2
上例定義一個名為numberOfLegs的變數並用一個字典字面量初始化出了包含三對鍵值的字典執行個體。numberOfLegs的字典存放值類型推斷為Dictionary<String, Int>。字典執行個體建立完成之後通過附屬指令碼的方式將整型值2賦值到字典執行個體的索引為bird的位置中。