서브스크립트는 설정자나 접근자의 메서드를 구현하지 않고 타입의 요소에 접근할 수 있는 단축 문법이다. 서브스크립트는 여러 개를 구현할 수 있으며 전달하는 값의 타입을 유추해서 적절한 서브스크립트를 실행하게 된다. 또, 여러 개의 매개변수를 갖을 수 있지만 통상 하나의 매개변수를 갖고 입출력 매개변수는 갖을 수 없다.
서브스크립트의 기본 문법은 다음과 같다.
매개변수의 타입은 Int
가 아닌 다른 타입도 가능하다.
subscript(index: Int) -> Int {
get {
// 접근 - 서브스크립트의 결괏값을 반환
}
set(newValue) {
// 설정 - newValue값으로 설정
}
}
만약, 서브스크립트를 읽기전용으로 구현하려면 2가지 방식이 있다.
// 1번 방식 - set 구현 X
subscript(index: Int) -> Int {
get {
// 서브스크립트 결괏값 반환
}
}
// 2번 방식 - get, set 구현 X
subscript(index: Int) -> Int {
// 서브스크립트 결괏값 반환
}
struct Train {
var line: Int = 1 // 호선
var number: Int = 10000 // 전철번호
}
// 철도 회사 클래스
class Metro {
var trains: [Train] = [Train]() // 회사 소유 전철 배열
var number: Int = 10000 // 전철번호
// Train 인스턴스 생성 후 배열에 저장
func addTrain(line: Int){
let train: Train = Train(line: line, number: self.number)
self.trains.append(train)
self.number += 1
}
subscript(index: Int) -> Train? { // nil도 반환할 수 있어서 옵셔널
get {
// 인덱스 값이 최대 전철번호보다 작은지 검사 -> 생성되지 않은 전철 접근하는 오류 방지
if index < number {
return self.trains[index-10000]
}
return nil
}
set(newValue) {
guard var newTrain: Train = newValue else { return }
var number: Int = index
// 인덱스 값은 전철번호보다 더 커질 수 없다.
if index > self.number {
number = self.number
self.number += 1
}
newTrain.number = number
self.trains[number-10000] = newTrain
}
}
}
let seoulMetro: Metro = Metro()
seoulMetro.addTrain(line: 1) // 호선 : 1, 전철번호 : 100000
seoulMetro.addTrain(line: 2) // 호선 : 2, 전철번호 : 100001
// get
let firstTrain: Train? = seoulMetro[10000]
print("호선: \(firstTrain?.line), 전철번호: \(firstTrain?.number)")
// 출력 -> 호선: Optional(1), 전철번호: Optional(10000)
// set
seoulMetro[10000] = Train(line: 3)
print("호선: \(seoulMetro[10000]?.line), 전철번호: \(seoulMetro[10000]?.number)")
// 출력 -> 호선: Optional(3), 전철번호: Optional(10000)
Train
클래스 내부의 trains
배열을 set
부분에서 출력하면
전철번호 10000의 호선이 3으로 바껴있는 것을 볼 수 있다.
이처럼 서브스크립트를 사용하면 쉽게 인스턴스의 값에 접근하거나 설정할 수 있다.