목차
클래스, 구조체, 열거형에는 컬렉션, 리스트, 시퀀스 등 타입 요소에 접근하는 단축 문법인 서브스크립트를 정의할 수 있다. 별도의 설정자와 접근자 등의 메서드를 구현하지 않아도 인덱스를 통해 값을 설정하거나 가져올 수 있다.
서브스크립트를 여러 개 구현해도 외부에서 서브스크립트를 사용할 때는 전달한 값의 타입을 유추하여 적절한 서브스크립트를 선택하여 실행한다. 여러 서브스크립트를 한 타입에 구현하는 것을 서브스크립트 중복 정의(Subscript Overloading)이라고 한다.
서브스크립트는 보통 하나의 매개변수를 갖지만, 타입에 따라 여러 매개변수를 갖는 경우도 있다. 매개변수의 타입과 반환 타입에는 제한이 없다. 함수와 마찬가지로 서브스크립트는 여러 개의 매개변수를 가질 수 있고, 매개변수 기본값을 가질 수 있다. 그러나 입출력 매개변수는 가질 수 없다.
서브스크립트는 인스턴스의 이름 뒤에 대괄호로 감싼 값을 써줌으로써 인스턴스 내부의 특정 값에 접근할 수 있다.
서브스크립트는 subscript 키워드를 사용하여 정의한다. 인스턴스 메서드와 비슷하게 매개변수의 개수, 타입, 반환 타입 등을 지정하며, 읽고 쓰기가 가능하도록 구현하거나 읽기 전용으로만 구현할 수 있다. 서브스크립트를 정의하는 코드는 각 타입의 구현부나 타입의 익스텐션 구현부에 위치해야 한다.
매개변수를 따로 명시해주지 않으면 설정자의 암시적 전달인자 newValue를 사용할 수 있다. 읽기 전용 프로퍼티를 구현할 때는 get, set 키워드를 사용하지 않고 적절한 값만 반환하는 형태로 구현해도 된다.
subscript(index: Int) -> Int {
get { }
set(newValue) { } //newValue의 타입은 반환 타입과 동일하다.
}
//읽기 전용
subscript(index: Int) -> Int {
get { }
}
subscript(index: Int) -> Int { }
struct Student {
var name: String
var number: Int
}
class School {
var number: Int = 0
var students: [Student] = [Student]()
func addStudent(name: String) {
let student: Student = Student(name: name, number: self.number)
self.students.append(student)
self.number += 1
}
func addStudents(names: String...) {
for name in names {
self.addStudent(name)
}
}
subscript(index: Int = 0) -> Student? {
if index < self.number {
return self.students[index]
}
return nil
}
}
let highSchool: School = School()
highSchool.addStudents(names: "Taekang", "Jeongwon", "Ppomi")
let aStudent: Student? = highSchool[1]
print("\\(aStudent?.number) \\(aStudent?.name)") //Optional(1) Optional("Jeongwon")
print(highSchool[]?.name) //Optional("Taekang")