Swift 下標指令碼(Subscripts)
本頁包含內容:
下標指令碼 可以定義在類(Class)、結構體(structure)和列舉(enumeration)這些目標中,可以認為是訪問集合(collection),列表(list)或序列(sequence的快捷方式,使用下標指令碼的索引設定和獲取值,不需要再呼叫例項的特定的賦值和訪問方法。舉例來說,用下標指令碼訪問一個陣列(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)
print("3的6倍是\(threeTimesTable[6])")
// 輸出 "3的6倍是18"
在上例中,通過TimesTable
結構體建立了一個用來表示索引值三倍的例項。數值3
作為結構體建構函式
入參初始化例項成員multiplier
。
你可以通過下標指令碼來得到結果,比如threeTimesTable[6]
。這條語句訪問了threeTimesTable
的第六個元素,返回6
的3
倍即18
。
注意:
TimesTable
例子是基於一個固定的數學公式。它並不適合對threeTimesTable[someIndex]
進行賦值操作,這也是為什麼附屬指令碼只定義為只讀的原因。
下標指令碼用法
根據使用場景不同下標指令碼也具有不同的含義。通常下標指令碼是用來訪問集合(collection),列表(list)或序列(sequence)中元素的快捷方式。你可以在你自己特定的類或結構體中自由的實現下標指令碼來提供合適的功能。
例如,Swift 的字典(Dictionary)實現了通過下標指令碼來對其例項中存放的值進行存取操作。在下標指令碼中使用和字典索引相同型別的值,並且把一個字典值型別的值賦值給這個下標指令碼來為字典設值:
var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
numberOfLegs["bird"] = 2
上例定義一個名為numberOfLegs
的變數並用一個字典字面量初始化出了包含三對鍵值的字典例項。numberOfLegs
的字典存放值型別推斷為[String:Int]
。字典例項建立完成之後通過下標指令碼的方式將整型值2
賦值到字典例項的索引為bird
的位置中。
更多關於字典(Dictionary)下標指令碼的資訊請參考讀取和修改字典
注意:
Swift 中字典的附屬指令碼實現中,在get
部分返回值是Int?
,上例中的numberOfLegs
字典通過附屬指令碼返回的是一個Int?
或者說“可選的int”,不是每個字典的索引都能得到一個整型值,對於沒有設過值的索引的訪問返回的結果就是nil
;同樣想要從字典例項中刪除某個索引下的值也只需要給這個索引賦值為nil
即可。
下標指令碼選項
下標指令碼允許任意數量的入參索引,並且每個入參型別也沒有限制。下標指令碼的返回值也可以是任何型別。下標指令碼可以使用變數引數和可變引數,但使用寫入讀出(in-out)引數或給引數設定預設值都是不允許的。
一個類或結構體可以根據自身需要提供多個下標指令碼實現,在定義下標指令碼時通過入參的型別進行區分,使用下標指令碼時會自動匹配合適的下標指令碼實現執行,這就是下標指令碼的過載。
一個下標指令碼入參是最常見的情況,但只要有合適的場景也可以定義多個下標指令碼入參。如下例定義了一個Matrix
結構體,將呈現一個Double
型別的二維矩陣。Matrix
結構體的下標指令碼需要兩個整型引數:
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
提供了一個兩個入參的構造方法,入參分別是rows
和columns
,建立了一個足夠容納rows * columns
個數的Double
型別陣列。通過傳入陣列長度和初始值0.0到陣列的一個構造器,將Matrix
中每個元素初始值0.0。關於陣列的構造方法和析構方法請參考建立一個空陣列。
你可以通過傳入合適的row
和column
的數量來構造一個新的Matrix
例項:
var matrix = Matrix(rows: 2, columns: 2)
上例中建立了一個新的兩行兩列的Matrix
例項。在閱讀順序從左上到右下的Matrix
例項中的陣列例項grid
是矩陣二維陣列的扁平化儲存:
// 示意圖
grid = [0.0, 0.0, 0.0, 0.0]
col0 col1
row0 [0.0, 0.0,
row1 0.0, 0.0]
將值賦給帶有row
和column
下標指令碼的matrix
例項表示式可以完成賦值操作,下標指令碼入參使用逗號分割
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
中同時呼叫了下標指令碼入參的row
和column
是否有效的判斷。為了方便進行斷言,Matrix
包含了一個名為indexIsValidForRow(_:column:)
的成員方法,用來確認入參的row
或column
值是否會造成陣列越界:
func indexIsValidForRow(row: Int, column: Int) -> Bool {
return row >= 0 && row < rows && column >= 0 && column < columns
}
斷言在下標指令碼越界時觸發:
let someValue = matrix[2, 2]
// 斷言將會觸發,因為 [2, 2] 已經超過了matrix的最大長度
相關文章
- Swift2.0語言教程之下標指令碼Swift指令碼
- Swift-下標Swift
- Swift,下標簡化方法的呼叫Swift
- 排序策略 - Swift標準庫原始碼排序Swift原始碼
- html指令碼 標籤與HTML指令碼
- 導庫標準引數指令碼指令碼
- 建庫指令碼下載指令碼
- swift指令碼程式設計:一鍵生成AppIconSwift指令碼程式設計APP
- 第六章——函式(計算屬性和下標指令碼)函式指令碼
- Swift標準庫原始碼閱讀筆記 - DictionarySwift原始碼筆記
- 指令碼日誌的標準輸出指令碼
- IOS開發:Swift中附屬指令碼的使用說明iOSSwift指令碼
- Windows下RMAN備份指令碼Windows指令碼
- UNIX下oracle啟動指令碼Oracle指令碼
- RAC模式下的rman指令碼模式指令碼
- Swift標準庫解析:IntSwift
- Swift 中的指標使用Swift指標
- Swift中指標使用指南Swift指標
- Centos下使用php呼叫shell指令碼CentOSPHP指令碼
- 資料匯入shell指令碼(下)指令碼
- WINDOWS下 部署 rman 全備指令碼Windows指令碼
- linux下rman增量備份指令碼以及指令碼自動執行Linux指令碼
- 【Oracle指令碼】-很不錯的Windows下資料庫備份EXP指令碼Oracle指令碼Windows資料庫
- Swift指令碼(二):無失真壓縮專案中的png檔案Swift指令碼
- windows bat指令碼 後臺執行目標exeWindowsBAT指令碼
- 【RMAN】RMAN指令碼中使用替換變數--windows 下rman全備指令碼指令碼變數Windows
- Swift中的值和指標Swift指標
- [譯]Swift 結構體指標Swift結構體指標
- Linux下pppd撥號指令碼配置Linux指令碼
- Oracle:GRID 下 root.sh 指令碼Oracle指令碼
- MySQL:Windows下分庫備份指令碼MySqlWindows指令碼
- linux 下RMAN備份shell指令碼Linux指令碼
- WIN下的普通備份指令碼示例指令碼
- Linux 下oracle自啟動指令碼LinuxOracle指令碼
- AIX環境下監控程式指令碼AI指令碼
- windows下rman自動備份指令碼Windows指令碼
- Linux下如何執行Shell指令碼Linux指令碼
- windows下oracle自動啟動指令碼WindowsOracle指令碼