ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Subscripts
    iOS/Swift 공식문서 2022. 2. 19. 16:59

    Subscript란?

    collection, list, sequence의 member element에 간단하게 접근할 수 있는 문법으로, 클래스, 구조체, 열거형에서 정의할 수 있다. 인덱스를 통해 특정 값에 접근할 수 있게 하기 위해 사용한다. 예를 들어 배열의 경우 arr[index]로 특정 element에 접근할 수 있다. 하나의 타입에 대하여 여러 subscript를 정의할 수도 있고 오버로딩도 가능하다.

     

    Subscript Syntax

    subscript는 인스턴스 이름 뒤에 한 개 이상의 값을 [] 안에 적음으로써 사용할 수 있다. 문법은 인스턴스 메서드나 computed property와 비슷하다. subscript 키워드와 함께, 매개변수 타입과 리턴 타입을 명시하고, getter와 setter를 구현한다. read-only나 read-write 둘 중 하나만 가능하므로 getter는 필수이고, setter는 선택이다.

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

     

    Subscript Usage

    다음 예를 살펴보자. Swift의 Dictionary 타입은 인스턴스에 저장된 값을 바꾸거나 사용할 수 있도록 subscript가 정의되어 있다. 값을 설정하고자 하면 좌변의 [] 안에 key를 넣고, 우변에 value를 할당하면 된다. 저장된 값에 접근하고자 하면 인스턴스 이름을 적고, []안에 key를 넣어주면 된다. 반환 타입은 optional이다. 해당 key 값을 가진 pair가 없을 수 있기 때문이다.

    var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
    numberOfLegs["bird"] = 2
    print(numberOfLegs["bird"]) // Optional(2)

     

    Subscript Options

    subscript의 매개변수도 다른 함수의 매개변수처럼 개수 제한이 없고, 어느 타입이라도 사용할 수 있다. 또한 리턴 타입에도 제한이 없다. 또한 variadic paramter와 default paramter도 사용할 수 있다. 그러나 in-out paramter는 불가능하다.

    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
            }
        }
    }
    
    var matrix = Matrix(rows: 2, columns: 2)
    matrix[0, 1] = 1.5
    matrix[1, 0] = 3.2
    
    let someValue = matrix[2, 2]
    // This triggers an assert, because [2, 2] is outside of the matrix bounds.

     

    클래스 혹은 구조체는 필요한 만큼 많은 subscript를 구현할 수 있다. 또한 사용된 인자 값들에 따라 적절한 subscript가 사용될 것이다. 여러 subscript를 정의하는 것을 subscript overloading이라 한다.

     

    Type Subscripts

    인스턴스에서 호출하는 subscript를 instance subscript라 한다. 타입 자체에서 호출하는 subscript도 정의할 수 있는데, 이를 type subscript라 한다. 앞에 static 키워드를 적으면 된다. 클래스의 경우 subclass의 오버라이딩을 허용하기 위해 static 대신 class 키워드를 사용할 수 있다.

    enum Planet: Int {
        case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
        static subscript(n: Int) -> Planet {
            return Planet(rawValue: n)!
        }
    }
    let mars = Planet[4]
    print(mars)

     

    Reference

    https://docs.swift.org/swift-book/LanguageGuide/Subscripts.html

    'iOS > Swift 공식문서' 카테고리의 다른 글

    Initialization  (0) 2022.02.21
    Inheritance  (0) 2022.02.20
    Methods  (0) 2022.02.19
    Properties  (0) 2022.02.18
    Structures and Classes  (0) 2022.02.17

    댓글

Designed by Tistory.