定義下標(biāo)使用subscript關(guān)鍵字, 形式如下:
subscript(index: Int) -> Int {
get {
// 返回一個(gè)適當(dāng)?shù)?Int 類型的值
}
set(newValue) {
// 執(zhí)行適當(dāng)?shù)馁x值操作
}
}
只讀下標(biāo)的實(shí)現(xiàn) 例:
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"
在上例中,創(chuàng)建了一個(gè)TimesTable實(shí)例,用來(lái)表示整數(shù)3的乘法表。數(shù)值3被傳遞給結(jié)構(gòu)體的構(gòu)造函數(shù),作為實(shí)例成員multiplier的值。
下標(biāo)用法
下標(biāo)的確切含義取決于使用場(chǎng)景。下標(biāo)通常作為訪問(wèn)集合,列表或序列中元素的快捷方式。你可以針對(duì)自己特定的類或結(jié)構(gòu)體的功能來(lái)自由地以最恰當(dāng)?shù)姆绞綄?shí)現(xiàn)下標(biāo)。
下標(biāo)選項(xiàng)
- 下標(biāo)可以接受任意數(shù)量的入?yún)ⅲ⑶疫@些入?yún)⒖梢允侨我忸愋?。下?biāo)的返回值也可以是任意類型。下標(biāo)可以使用變量參數(shù)和可變參數(shù),但不能使用輸入輸出參數(shù),也不能給參數(shù)設(shè)置默認(rèn)值。
- 一個(gè)類或結(jié)構(gòu)體可以根據(jù)自身需要提供多個(gè)下標(biāo)實(shí)現(xiàn),使用下標(biāo)時(shí)將通過(guò)入?yún)⒌臄?shù)量和類型進(jìn)行區(qū)分,自動(dòng)匹配合適的下標(biāo),這就是下標(biāo)的重載。
雖然接受單一入?yún)⒌南聵?biāo)是最常見(jiàn)的,但也可以根據(jù)情況定義接受多個(gè)入?yún)⒌南聵?biāo)。例如下例定義了一個(gè)Matrix結(jié)構(gòu)體,用于表示一個(gè)Double類型的二維矩陣。Matrix結(jié)構(gòu)體的下標(biāo)接受兩個(gè)整型參數(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) + column] = newValue
}
}
}
Matrix提供了一個(gè)接受兩個(gè)入?yún)⒌臉?gòu)造方法,入?yún)⒎謩e是rows和columns,創(chuàng)建了一個(gè)足夠容納rows * columns個(gè)Double類型的值的數(shù)組。通過(guò)傳入數(shù)組長(zhǎng)度和初始值0.0到數(shù)組的構(gòu)造器,將矩陣中每個(gè)位置的值初始化為0.0
你可以通過(guò)傳入合適的row和column的數(shù)量來(lái)構(gòu)造一個(gè)新的Matrix實(shí)例:
var matrix = Matrix(rows: 2, columns: 2)
將row和column的值傳入下標(biāo)來(lái)為矩陣設(shè)值,下標(biāo)的入?yún)⑹褂枚禾?hào)分隔:
matrix[0, 1] = 1.5
matrix[1, 0] = 3.2
Matrix下標(biāo)的 getter 和 setter 中都含有斷言,用來(lái)檢查下標(biāo)入?yún)ow和column的值是否有效。為了方便進(jìn)行斷言,Matrix包含了一個(gè)名為indexIsValidForRow(_:column:)的便利方法,用來(lái)檢查入?yún)ow和column的值是否在矩陣范圍內(nèi):
func indexIsValidForRow(row: Int, column: Int) -> Bool {
return row >= 0 && row < rows && column >= 0 && column < columns
}
斷言在下標(biāo)越界時(shí)觸發(fā):
let someValue = matrix[2, 2]
// 斷言將會(huì)觸發(fā),因?yàn)?[2, 2] 已經(jīng)超過(guò)了 matrix 的范圍