[Swift] Subscript

나는 사과·2021년 3월 5일
0

TIL

목록 보기
4/18

서브스크립트

서브스크립트는 설정자나 접근자의 메서드를 구현하지 않고 타입의 요소에 접근할 수 있는 단축 문법이다. 서브스크립트는 여러 개를 구현할 수 있으며 전달하는 값의 타입을 유추해서 적절한 서브스크립트를 실행하게 된다. 또, 여러 개의 매개변수를 갖을 수 있지만 통상 하나의 매개변수를 갖고 입출력 매개변수는 갖을 수 없다.

기본 문법

서브스크립트의 기본 문법은 다음과 같다.
매개변수의 타입은 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으로 바껴있는 것을 볼 수 있다.
이처럼 서브스크립트를 사용하면 쉽게 인스턴스의 값에 접근하거나 설정할 수 있다.

0개의 댓글

관련 채용 정보