Swift 下標指令碼

下標指令碼 可以定義在類(Class)、結構體(structure)和列舉(enumeration)這些目標中,可以認為是訪問物件、集合或序列的快捷方式,不需要再呼叫例項的特定的賦值和訪問方法。

舉例來說,用下標指令碼訪問一個數組(Array)例項中的元素可以這樣寫 someArray[index] ,訪問字典(Dictionary)例項中的元素可以這樣寫 someDictionary[key]。

對於同一個目標可以定義多個下標指令碼,通過索引值型別的不同來進行過載,而且索引值的個數可以是多個。


下標指令碼語法及應用

語法

下標指令碼允許你通過在例項後面的方括號中傳入一個或者多個的索引值來對例項進行訪問和賦值。

語法類似於例項方法和計算型屬性的混合。

與定義例項方法類似,定義下標指令碼使用subscript關鍵字,顯式宣告入參(一個或多個)和返回型別。

與例項方法不同的是下標指令碼可以設定為讀寫或只讀。這種方式又有點像計算型屬性的getter和setter:

subscript(index: Int) -> Int {
    get {
        // 用於下標指令碼值的宣告
    }
    set(newValue) {
        // 執行賦值操作
    }
}

例項 1

import Cocoa

struct subexample {
    let decrementer: Int
    subscript(index: Int) -> Int {
        return decrementer / index
    }
}
let division = subexample(decrementer: 100)

print("100 除以 9 等於 \(division[9])")
print("100 除以 2 等於 \(division[2])")
print("100 除以 3 等於 \(division[3])")
print("100 除以 5 等於 \(division[5])")
print("100 除以 7 等於 \(division[7])")

以上程式執行輸出結果為:

100 除以 9 等於 11
100 除以 2 等於 50
100 除以 3 等於 33
100 除以 5 等於 20
100 除以 7 等於 14

在上例中,通過 subexample 結構體建立了一個除法運算的例項。數值 100 作為結構體建構函式傳入引數初始化例項成員 decrementer。

你可以通過下標指令碼來得到結果,比如 division[2] 即為 100 除以 2。

例項 2

import Cocoa

class daysofaweek {
    private var days = ["Sunday", "Monday", "Tuesday", "Wednesday",
        "Thursday", "Friday", "saturday"]
    subscript(index: Int) -> String {
        get {
            return days[index]   // 宣告下標指令碼的值
        }
        set(newValue) {
            self.days[index] = newValue   // 執行賦值操作
        }
    }
}
var p = daysofaweek()

print(p[0])
print(p[1])
print(p[2])
print(p[3])

以上程式執行輸出結果為:

Sunday
Monday
Tuesday
Wednesday

用法

根據使用場景不同下標指令碼也具有不同的含義。

通常下標指令碼是用來訪問集合(collection),列表(list)或序列(sequence)中元素的快捷方式。

你可以在你自己特定的類或結構體中自由的實現下標指令碼來提供合適的功能。

例如,Swift 的字典(Dictionary)實現了通過下標指令碼對其例項中存放的值進行存取操作。在下標指令碼中使用和字典索引相同型別的值,並且把一個字典值型別的值賦值給這個下標腳來為字典設值:

import Cocoa

var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
numberOfLegs["bird"] = 2

print(numberOfLegs)

以上程式執行輸出結果為:

["ant": 6, "bird": 2, "cat": 4, "spider": 8]

上例定義一個名為numberOfLegs的變數並用一個字典字面量初始化出了包含三對鍵值的字典例項。numberOfLegs的字典存放值型別推斷為Dictionary。字典例項建立完成之後通過下標指令碼的方式將整型值2賦值到字典例項的索引為bird的位置中。


下標指令碼選項

下標指令碼允許任意數量的入參索引,並且每個入參型別也沒有限制。

下標指令碼的返回值也可以是任何型別。

下標指令碼可以使用變數引數和可變引數。

一個類或結構體可以根據自身需要提供多個下標指令碼實現,在定義下標指令碼時通過傳入引數的型別進行區分,使用下標指令碼時會自動匹配合適的下標指令碼實現執行,這就是下標指令碼的過載

import Cocoa

struct Matrix {
    let rows: Int, columns: Int
    var print: [Double]
    init(rows: Int, columns: Int) {
        self.rows = rows
        self.columns = columns
        print = Array(repeating: 0.0, count: rows * columns)
    }
    subscript(row: Int, column: Int) -> Double {
        get {
            return print[(row * columns) + column]
        }
        set {
            print[(row * columns) + column] = newValue
        }
    }
}
// 建立了一個新的 3 行 3 列的Matrix例項
var mat = Matrix(rows: 3, columns: 3)

// 通過下標指令碼設定值
mat[0,0] = 1.0
mat[0,1] = 2.0
mat[1,0] = 3.0
mat[1,1] = 5.0

// 通過下標指令碼獲取值
print("\(mat[0,0])")
print("\(mat[0,1])")
print("\(mat[1,0])")
print("\(mat[1,1])")

以上程式執行輸出結果為:

1.0
2.0
3.0
5.0

Matrix 結構體提供了一個兩個傳入引數的構造方法,兩個引數分別是rows和columns,建立了一個足夠容納rows * columns個數的Double型別陣列。為了儲存,將陣列的大小和陣列每個元素初始值0.0。

你可以通過傳入合適的row和column的數量來構造一個新的Matrix例項。