Subscripts : collection/list/sequence 의 요소에 접근하기 위한 shortcut.
하나의 type 에 여러 subscript 를 정의할 수 있고, subscript 에 전달하는 index 의 type 에 따라 적절한 subscript 를 선택할 수 있음. Subscript 는 일차원에 한정되어 있지 않고, 여러 input parameter 를 넣을 수 있는 subscript 를 정의할 수 있음
Subscript 는 instance 이름 뒤의 대괄호 [] 에 하나 이상의 값을 써서 instance 에 query 를 할 수 있게 해줌.
subscript 키워드를 써서 subscript 정의를 작성. Subscript 를 작성하는 문법은 method, computed property 문법과 비슷함. Instance 메서드와는 다르게 subscript 는 read-write 거나 read-only 임.
subscript(index: Int) -> Int {
get {
// Return an appropriate subscript value here.
}
// 만약 setter 에 parameter 를 전달하지 않는다면 newValue 라는 기본 이름이 사용됨
set(newValue) {
// Perform a suitable setting action here.
}
}
// read-only subscript
subscript(index: Int) -> Int {
// Return an appropriate subscript value here.
}
struct TimesTable {
let multiplier: Int
subscript(index: Int) -> Int {
return multiplier * index
}
}
let threeTimesTable = TimesTable(multiplier: 3)
print("six times three is \(threeTimesTable[6])")
// Prints "six times three is 18".
Subscript 는 사용되는 문맥에 따라 달라짐. 주로 collection/list/sequence 에 있는 요소들을 접근하기 위한 shortcut 으로 사용됨.
e.g. Dictionary type 은 instance 에 저장된 값을 가져오고 설정하기 위한 subscript 를 구현함
var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
numberOfLegs["bird"] = 2
Subscript 는 여러 개의 input parameter 를 받을 수 있고, parameter 들은 어떤 타입이든 될 수 있으며 subscript 가 return 하는 타입은 어떤 타입이든 가능함.
Subscript 는 variadic parameter, default value 를 parameter 가 가질 수 있지만 in-out parameter 는 가질 수 없음.
Class, struct 는 가능한 한 많은 subscript 을 구현할 수 있고, 가장 적절한 subscript 는 subscript 괄호 안에 사용된 값의 타입이나 그 값에 의해 추론됨
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
}
}
}
matrix[0, 1] = 1.5
matrix[1, 0] = 3.2
Type 자체에 호출할 수 있는 subscript 를 정의할 수도 있음.
subscript 키워드 전에 static 키워드를 써서 type subscript 를 작성함. Class 는 class 키워드를 써서 subclass 가 해당 subscript 의 구현을 override 할 수 있게 함
enum Planet: Int {
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
static subscript(n: Int) -> Planet {
return Planet(rawValue: n)!
}
}
let mars = Planet[4]
print(mars)