下標腳本允許任意數(shù)量的入?yún)⑺饕⑶颐總€入?yún)㈩愋鸵矝]有限制。下標腳本的返回值也可以是任何類型。下標腳本可以使用變量參數(shù)和可變參數(shù),但使用寫入讀出(in-out)參數(shù)或給參數(shù)設(shè)置默認值都是不允許的。
一個類或結(jié)構(gòu)體可以根據(jù)自身需要提供多個下標腳本實現(xiàn),在定義下標腳本時通過入?yún)€類型進行區(qū)分,使用下標腳本時會自動匹配合適的下標腳本實現(xiàn)運行,這就是下標腳本的重載。
一個下標腳本入?yún)⑹亲畛R姷那闆r,但只要有合適的場景也可以定義多個下標腳本入?yún)?。如下例定義了一個Matrix結(jié)構(gòu)體,將呈現(xiàn)一個Double類型的二維矩陣。Matrix結(jié)構(gòu)體的下標腳本需要兩個整型參數(shù):
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) + columns] = newValue
}
}
}
Matrix提供了一個兩個入?yún)⒌臉?gòu)造方法,入?yún)⒎謩e是rows和columns,創(chuàng)建了一個足夠容納rows * columns個數(shù)的Double類型數(shù)組。為了存儲,將數(shù)組的大小和數(shù)組每個元素初始值0.0,都傳入數(shù)組的構(gòu)造方法中來創(chuàng)建一個正確大小的新數(shù)組。關(guān)于數(shù)組的構(gòu)造方法和析構(gòu)方法請參考創(chuàng)建并且構(gòu)造一個數(shù)組。
你可以通過傳入合適的row和column的數(shù)量來構(gòu)造一個新的Matrix實例:
var matrix = Matrix(rows: 2, columns: 2)
上例中創(chuàng)建了一個新的兩行兩列的Matrix實例。在閱讀順序從左上到右下的Matrix實例中的數(shù)組實例grid是矩陣二維數(shù)組的扁平化存儲:
// 示意圖
grid = [0.0, 0.0, 0.0, 0.0]
col0 col1
row0 [0.0, 0.0,
row1 0.0, 0.0]
將值賦給帶有row和column下標腳本的matrix實例表達式可以完成賦值操作,下標腳本入?yún)⑹褂枚禾柗指?/p>
matrix[0, 1] = 1.5
matrix[1, 0] = 3.2
上面兩條語句分別讓matrix的右上值為 1.5,坐下值為 3.2:
[0.0, 1.5,
3.2, 0.0]
Matrix下標腳本的getter和setter中同時調(diào)用了下標腳本入?yún)⒌?code style="box-sizing: border-box; -webkit-tap-highlight-color: transparent; -webkit-font-smoothing: antialiased; font-family: Monaco, Menlo, Consolas, 'Courier New', monospace; font-size: 14px; padding: 0px 5px; color: rgb(199, 37, 78); background-color: rgb(248, 248, 248); white-space: nowrap; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; margin: 0px 2px; border: 1px solid rgb(234, 234, 234);">row和column是否有效的判斷。為了方便進行斷言,Matrix包含了一個名為indexIsValid的成員方法,用來確認入?yún)⒌?code style="box-sizing: border-box; -webkit-tap-highlight-color: transparent; -webkit-font-smoothing: antialiased; font-family: Monaco, Menlo, Consolas, 'Courier New', monospace; font-size: 14px; padding: 0px 5px; color: rgb(199, 37, 78); background-color: rgb(248, 248, 248); white-space: nowrap; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; margin: 0px 2px; border: 1px solid rgb(234, 234, 234);">row或column值是否會造成數(shù)組越界:
func indexIsValidForRow(row: Int, column: Int) -> Bool {
return row >= 0 && row < rows && column >= 0 && column < columns
}
斷言在下標腳本越界時觸發(fā):
let someValue = matrix[2, 2]
// 斷言將會觸發(fā),因為 [2, 2] 已經(jīng)超過了matrix的最大長度