サブスクリプトとは??
クラス構造体列挙体は、コレクション、リストまたはシーケンスのメンバー要素にアクセスするためのショートカットである添え字を定義できます。
つまりサブスクリプトとは型が配列等の要素にアクセスするためのショートカットのこと!
何がメリットなのか
使用することによって、値の取得・設定をしたい時にわざわざメソッドを用いる必要がなくなり、サブスクリプトのインデックスの値によって行えることです!
構文
クラス・構造体・列挙体の中で、subscript(引数)->戻り値{return ~~}
という構文で記述します。
下のコード例では、
threeTimesTable[6]
により、TimesTable内のsubscriptのindex
に6が代入され、戻り値を返します。
struct TimesTable{
let multiplier: Int
subscript(index: Int) -> Int{ //indexには6がはいる
return multiplier * index //read-only
}
}
let threeTimesTable = TimesTable(multiplier: 3)
print("six times three is \(threeTimesTable[6])") //threeTimesTable[6]がサブスク!
サブスクの特徴1「複数のパラメーターを持てる」
サブスクリプトは、複数のパラメータを持つことができます!
下のコード例では、subscript(row:Int, column:Int)
とあるように2つのパラメータを持ってます。
struct Matrix{
let rows: Int, columns: Int
var grid: [Double]
init(rows:Int, columns:Int){
self.rows = rows
self.columns = columns
grid = Array(repeating: 0.0, count: rows * columns)
}
func indexIsValid(row: Int, column:Int) -> Bool {
return row >= 0 && row < rows && column >= 0 && column < columns
}
subscript(row:Int, column:Int) -> Double{
get{
assert(indexIsValid(row: row, column: column), "Index out of range")
return grid[(row * columns) + column]
}
set{
assert(indexIsValid(row: row, column: column), "Index out of range")
grid[(row * columns) + column] = newValue //サブスクで渡された値を元にgrid[]を更新
}
}
}
var matrix = Matrix(rows: 2, columns: 2)
print(matrix) //サブスク前の出力:Matrix(rows: 2, columns: 2, grid: [0.0, 0.0, 0.0, 0.0])
matrix[0,1] = 1.5 //サブスク
matrix[1,0] = 2.5 //サブスク
print(matrix) //サブスク後の出力:Matrix(rows: 2, columns: 2, grid: [0.0, 1.5, 2.5, 0.0])
ちなみに、
assert(indexIsValid(row: row, column: column), "Index out of range")
については、初めてみたのでここに軽くassertについてメモしときます。
assert → 条件をチェックしfalseの場合はエラーとなる
構文:assert(条件式(Bool),"エラーメッセージ")
サブスクの特徴2「タイプに直接紐づけられる」
タイププロパティのように、タイプに直接紐づけることができます。
これまで紹介してきたサブスクは全てインスタンスサブスクです。
インスタンスに対して添え字を用いてますね。
threeTimesTable[6]
matrix[0,1] = 1.5
タイプサブスクリプトは、その名の通り、staticキーワード
を用いることでタイプ[0]
のようにタイプに直接サブスクを使えます!
enum Planet: Int {
case mercury = 1, vanus, earth, mars, jupiter, saturn, uranus, neptune
static subscript(n: Int) -> Planet{
return Planet(rawValue: n)!
}
}
let mars = Planet[4]
print(mars)