새소식

iOS/Swift

[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)

 

- 두 개의 읽고 쓰기 가능한 서브스크립트와 하나의 읽기 전용 서브 스크립트 구현됨

- 각각의 서브스크립트는 매개변수의 타입과 개수, 반환 타입이 모두 다름

 

  1. 첫 번째 서브스크립트는
    - 학생의 번호를 전달받아 해당하는 학생이 있다면 Student 인스턴트를 반환
    - 특정 번호의 학생을 할당

  2. 두 번째 서브스크립트는
    - 학생의 이름을 전달받아 해당하는 학생이 있다면 번호를 반환
    - 특정 이름의 학생을 해당하는 번호에 할당

  3. 세 번째 서브스크립트는
    - 이름과 번호를 전달받아 해당하는 학생이 있다면 찾아서 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

 

728x90

'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
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.