[Swift] 서브스크립트
참조 : Swift 스위프트 프로그래밍 3판 Swift 5, 저자 야곰 (한빛미디어) , The Swift Programming Language Swift 5.6 Edition (iBooks)(https://books.apple.com/kr/book/the-swift-programming-language-swift-5-6/id881256329)
서브스크립트(subscript)
- 클래스, 구조체, 열거형에는 컬렉션, 리스트, 시퀸스 등의 타입의 요소에 접근하는 단축 문법
- 별도의 설정자(Setter)와 접근자(Getter)등의 메서드를 구현하지 않아도 인덱스를 통해 값을 설정하거나 가져올 수 있음
- 서브스크립트 중복 정의(Subscript Overloading): 여러 서브스크립트를 한 타입에 구현하는 것
- 매개변수의 타입과 반환 타입에는 제한이 없음 → 여러 개의 매개변수를 가질 수 있고, 매개변수 기본값을 가질 수 있음
입출력 매개변수(in-out parameters)는 가질 수 없음
- subscript 키워드를 사용하여 선언
- 인스턴스 메서드와 비슷하게 매개변수의 개수, 타입, 반환 타입 등을 지정함
- 읽고 쓰기가 가능하도록 구현하거나 읽기 전용으로만 구현 가능
subscript(index: Int) -> Int{
get{
// 적절한 서브스크립트 결괏값 변환
}
set(newValue) {
// 적절한 설정자 역할 수행
}
}
- 설정자(Setter)의 newValue의 타입은 서버스크립트의 반환 타입과 동일
- 연산 프로퍼티와 마찬가지로 매개변수를 따로 명시해주지 않으면 설정자(Setter)의 암시적 전달인자 newValue를 사용 가능
- 읽기 전용 프로퍼티를 구현할 때는 get이나 set 키워드 없이 적절한 값만 반환해주는 형태로만 구현해도 됨
- 서브스크립트는 자신이 가지는 시퀸스나 컬렉션, 리스트 등의 요소를 반환하고 설정할 때 주로 사용
- School 클래스 서브스크립트 구현
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: name)
}
}
subscript(index: Int = 0) -> Student? {
if index < self.number{
return self.students[index]
}
return nil
}
}
let highSchool: School = School()
highSchool.addStudents(names: "MinJae", "HeungMin", "Kane")
let aStudent: Student? = highSchool[1]
print("\(aStudent?.number) \(aStudent?.name)") // Optional(1) Optional("HeungMin")
print(highSchool[]?.name) // Optional("MinJae")
- 학생의 번호를 전달인자로 전달받아 자신의 students 프로퍼티의 인덱스에 맞는 Student 인스턴스를 반환함
- 서브스크립트의 index 매개변수가 매개변수 기본값을 0으로 갖지만 필요하지 않으면 매개변수의 기본값이 없어도 상관없음
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: name)
}
}
subscript(index: Int = 0) -> Student? { // 첫 번째 서브스크립트
get{
if index < self.number{
return self.students[index]
}
return nil
}
set{
guard var newStudent: Student = newValue else{
return
}
var number: Int = index
if index > self.number{
number = self.number
self.number += 1
}
newStudent.number = number
self.students[number] = newStudent
}
}
subscript(name: String) -> Int?{ // 두 번째 서브스크립트
get{
return self.students.filter{ $0.name == name}.first?.number
}
set{
guard var number: Int = newValue else{
return
}
if number > self.number{
number = self.number
self.number += 1
}
let newStudent: Student = Student(name: name, number: number)
self.students[number] = newStudent
}
}
subscript(name: String, number: Int) -> Student?{ // 세 번째 서브스크립트
return self.students.filter{$0.name == name && $0.number == number}.first
}
}
let highSchool: School = School()
highSchool.addStudents(names: "MinJae", "HeungMin", "Kane", " Jenny", "V")
let aStudent: Student? = highSchool[1]
print("\(aStudent?.number) \(aStudent?.name)") // Optional(1) Optional("HeungMin")
print(highSchool["MinJae"]) // Optional(0)
print(highSchool["Kane"]) // Optional(2)
highSchool[0] = Student(name: "HwiJip", number: 0)
highSchool["Dog"] = 3
print(highSchool["MinJae"]) // nil
print(highSchool["Dog"]) // Optional(3)
- 두 개의 읽고 쓰기 가능한 서브스크립트와 하나의 읽기 전용 서브 스크립트 구현됨
- 각각의 서브스크립트는 매개변수의 타입과 개수, 반환 타입이 모두 다름
- 첫 번째 서브스크립트는
- 학생의 번호를 전달받아 해당하는 학생이 있다면 Student 인스턴트를 반환
- 특정 번호의 학생을 할당 - 두 번째 서브스크립트는
- 학생의 이름을 전달받아 해당하는 학생이 있다면 번호를 반환
- 특정 이름의 학생을 해당하는 번호에 할당 - 세 번째 서브스크립트는
- 이름과 번호를 전달받아 해당하는 학생이 있다면 찾아서 Student 인스턴스를 반환
타입 서브스크립트
- 서브스크립트는 인스턴스에서 사용할 수 있는 서브스크립트
- 타입 서브스크립트는 타입 자체에서 사용할 수 있는 서브스크립트
- subscript 키워드 앞에 static 키워드 붙여서 선언, 클래스의 경우에는 class 키워드를 사용할 수 있음
enum School:Int {
case elementary = 1, middle, high, university
static subscript(level: Int)-> School?{
return Self(rawValue: level)
}
}
let schhol:School? = School[2]
print(schhol) // School.middle
'iOS > Swift' 카테고리의 다른 글
[Swift] Extension (0) | 2022.09.27 |
---|---|
[Swift] 상속 (0) | 2022.09.25 |
[Swift] print(_:separator:terminator:) (0) | 2022.09.21 |
[Swift] 프로퍼티와 메서드 (0) | 2022.09.20 |
[Swift] 구조체와 클래스 (0) | 2022.09.16 |