Swift - 서브스크립트

임성빈·2022년 3월 26일
0

Swift

목록 보기
12/26
post-thumbnail
post-custom-banner

클래스, 구조체 그리고 열거형에서 스크립트를 정의해 사용할 수 있다.
서브스크립트란 콜렉션, 리스트, 시퀀스 등 집합의 특정 맴버 엘리먼트에 간단하게 접근할 수 있는 문법이다. 예를 들어 Array 인스턴스의 특정 엘리먼트는 someArray[index] 문법으로, Dictionary 인스턴스의 특정 엘리먼트는 someDictionary[index] 로 접근할 수 있다.

하나의 타입에 여러 서브스크립트를 정의할 수 있고 오버로드도 가능하다. 뿐만 아니라 인자값을 넘어 필요 따라 복수 인자값을 사용할 수 있다.


서브스크립트 문법

서브스크립트 선언 문법은 인스턴스 메소드와 계산된 프로퍼티를 선언하는 것과 비슷하다. 인스턴스 메소드와 다른 점은, 서브스크립트는 읽고-쓰기 혹은 읽기 전용만 가능하다는 것이다. 정의는 계산된 프로퍼티 방식과 같이 setter , getter 방식을 따른다.

subscript(index: Int) -> Int {
    get {
        // 적절한 반환 값
    }
    set(newValue) {
        // 적절한 set 액션
    }
}

서브스크립트의 set 에 대한 인자값을 따로 지정하지 않으면 기본값으로 newValue 를 사용한다. 읽기 전용으로 선언하면 get , set 을 지우고 따로 지정하지 않으면 get 으로 동작하게 되서 읽기 전용으로 선언된다.

subscript(index: Int) -> Int {
    // 적절한 반환 값
}

다음은 읽기 전용으로 선언한 서브스크립트이다.

struct TimesTable {
    let multiplier: Int
    subscript(index: Int) -> Int {
        return multiplier * index
    }
}
let threeTimesTable = TimesTable(multiplier: 3)
print("six times three is \(threeTimesTable[6])")
// "six times three is 18" 출력

서브스크립트 사용

다음은 Dictionary에서 서브스크립트의 사용이다.

var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
numberOfLegs["bird"] = 2

numberOfLegs 값은 타입 추론에 의해 [String: Int] 타입을 갖는다.
numberOfLegs["bird"] = 2 는 Dictionary 타입 변수 numberOfLegs 에 key로 bird를 그 값은 2를 넣으라는 서브스크립트 문법이다.

서브스크립트 옵션

서브스크립트는 입력 인자의 숫자에 제한이 없고, 입력 인자의 타입과 반환 타입의 제한도 없다. 다만 in-out 인자나 기본 인자값을 제공할 수는 없다. 서브스크립트는 오버로딩도 허용한다. 그래서 인자형, 반환형에 따라 원하는 수 만큼의 서브스크립트를 선언할 수 있다. 다음은 서브스크립트를 이용해 다차원 행렬을 선언하고 접근하는 예이다.

struct Matrix {
    let rows: Int, columns: Int
    var grid: [Double]
    init(rows: Int, columns: Int) {
        self.rows = rows
        self.columns = columns
        grid = Array(repeating: 0.0, count: rows * columns)
    }
    func indexIsValid(row: Int, column: Int) -> Bool {
        return row >= 0 && row < rows && column >= 0 && column < columns
    }
    subscript(row: Int, column: Int) -> Double {
        get {
            assert(indexIsValid(row: row, column: column), "Index out of range")
            return grid[(row * columns) + column]
        }
        set {
            assert(indexIsValid(row: row, column: column), "Index out of range")
            grid[(row * columns) + column] = newValue
        }
    }
}

위 코드에서 subscript(row: Int, column: Int) -> Double 코드와 같이 row, column 2개의 인자를 받고, Double 를 반환하는 서브스크립트를 선언했다. get, set 각각에 indexIsValid 메소드를 사용하여 유효한 index가 아닌 경우 프로그램이 바로 종료 되도록 assert 를 호출했다. 서브스크립트 문법 var matrix = Martrix(rows: 2, columns: 2) 을 이용해 2X2 행렬을 선언한다.

grid 배열은 서브스크립트에 의해 위와 같이 row와 column을 갖는 행렬도 동작한다. 행렬에 서브스크립트를 이용해 특정 row / column에 값을 넣을 수 있다.

matrix[0, 1] = 1.5
matrix[1, 0] = 3.2


행렬의 입출력시 row / column의 범위가 적절한지 아래의 코드로 확인한다.

func indexIsValid(row: Int, column: Int) -> Bool {
    return row >= 0 && row < rows && column >= 0 && column < columns
}

만약 적절한 범위를 벗어나면 assert가 실행된다.

let someValue = matrix[2, 2]
// [2, 2]가 사용할 수 있는 행렬의 범위를 벗어나므로 assert가 실행
profile
iOS 앱개발
post-custom-banner

0개의 댓글