Class、Struct、Enum 可以定義下標,它們均為訪問集合,列表或序列的成員元素的快捷方式。你可以利用下標通過索引值來設置和檢索值,不需要單獨的設置和檢索方法。
你可以為單個類型定義多個下標,並且下標會根據傳入的索引值的類型選擇適合的下標重載使用。下標沒有限制單個維度,你可以使用多個輸入形參來定義下標以滿足自定義類型的需求。
下標能夠讓你透過在實例名稱後面的方括號中寫上一個或多個值來查詢該類型的實例,它的語法類似於實例方法和計算屬性語法。你可以使用 subscript 關鍵字來定義下標,並以實例方法相同指定一個或多個輸入參數和返回類型,與實例方法不同,下標可以是「 可讀寫 」或是「 只能讀 」的。這個行為通過 getter 和 setter 傳達,與計算屬性中相同:
subscript(index: Int) -> Int {
get {
// 回傳一個適合的下標值
}
set(newValue) {
// 在這裡執行適合的設置操作
}
}
與計算屬性一樣,您可以選擇不指定 setter(newValue)參數。如果你自己沒有提供的話 , setter 默認提供形式參數 newValue 。
你可以給只讀下標省略 get 關鍵字:
subscript(index: Int) -> Int {
// 回傳一個適合的下標值
}
下面我們撰寫一個只讀的乘法運算例子:
struct Multiplication {
let number:Int
subscript(index:Int) -> Int{
return number * index
}
}
let mul = Multiplication(number: 10)
它表示通過給結構體的初始化轉入值 10 來作為用於實例 number 的參數。這時我們就能透過 mul[]來計算值:
下面我們示範一個可讀可寫的範例,並使用 day[] 來查看星期:
class Week {
var daysArray = ["Mon","Thu","Wed","Thr","Fri","Sat","Sun"]
subscript(index:Int) -> String {
get {
return daysArray[index]
}
set(newValue){
self.daysArray[index] = newValue
}
}
}
var day = Week()
顯示結果如下:
“下標”的確切含義取決於其使用的上下文。下標通常用作訪問集合,列表或序列中成員元素的快捷方式。你可以自由的用最適合的方式為特定的 class 或 struct 的功能實現下標。
例如,Swift 中的 Dictionary 可以在下標的方括號中通過提供字典鍵類型相同的鍵來設置字典裡的值,並且把一個與字典值類型相同的值給這個下標:
var queue = [ "apple":1 , "banana":2 , "cat": 3]
queue["dog"] = 4
//之後我們也可以利用相同的類型 [String : Int],加入一個 "dog" 鍵值和 Int 值為 4 到 queue 中
下標可以接受任何數量的輸入參數,並且這些參數可以是任何類型的。下標也可以返回任何類型。下標可以使用可變參數,但不能使用輸入輸出參數或是提供默認參數值。
類或結構體可以根據自身需要提供多個下標實現,合適被使用的下標會基於值類型或者使用下標時下標方括號裡包含的值來推斷。這個對多下標的定義就是所謂的下標重載( subscript overloading )。
我們用一個數學運算式來演示:
enum math{
case add, sub, mul, div
}
class Computer {
var result = 0
func calculate(Number1 a:Int ,Number2 b:Int , method:math) -> Int {
switch method {
case .add:
result = a + b
case .sub:
result = a - b
case .mul:
result = a * b
case .div:
result = a / b
}
return result
}
// 下標
subscript(Number1 a:Int ,Number2 b:Int , method:math) -> Int {
result = calculate(Number1: a, Number2: b, method: method)
return result
}
}
之後我們將它賦值到一個 mathMethod 實例中,透過下標來獲取對應的值,結果如下:
你最後一個例子是不是直接call function 沒有用到subscript
感謝Don大大的粉絲除錯,打太快沒注意到Sorry,已更新。