[Swift 4.0] Subscripts

IOS/Swift 2017. 4. 1. 23:17

Introduction
: subscript는 collection, list, sequence의 element에 접근하려고 할때 조금 더 편리한 방법을 제공하는 수단이다.
예를 들어 Array의 element를 접근할 때는 someArray[index], Dictionary의 element 접근할 때는 someDictionary[key]와 같이 subscript를 이용해서 편리하게 접근할 수 있다.

subscript는 Class, structure, enumeration에서 정의 가능하다.


Subscript Syntax
: "subscript" 키워드와 함께 정의한다. 그리고 하나이상의 input parameter와 return type을 정의해야 한다. 

subscript(index: Int) -> Int {

    get {

        // return an appropriate subscript value here

    }

    set(newValue) {

        // perform a suitable setting action here

    }

}

return value의 type은 newValue의 type과 동일하다. Computed property 처럼 newValue parameter를 생략할 수 있는데, 이 경우 "newValue"라는 이름이 자동할당 된다.

read-only 형식의 subscript도 정의할 수 있는데, 예시는 아래와 같다.

subscript(index: Int) -> Int {

    // return an appropriate subscript value here
}

set 메서드가 존재하지 않는다.
read-only subscript를 정의한 TimesTable 이라는 구조체를 만들어 보도록 하겠다.

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 Options
: Subscript는 input parameter 갯수의 제한은 없습니다. 이러한 parameter 들은 어떠한 type도 될 수 있고, 가변 파라미터 정의도 가능하다. 
그러나, in-out parameter, default parameter value는 사용이 불가능 하다.

Class, Structure는 multiple subscript를 구현할 수 있다. 이를 subscript overloading 이라 한다.

subscript는 보통 하나의 parameter를 받는게 일반적이지만, 필요에 따라 여러개의 parameter를 받도록 구현할 수 있다. 아래의 Matrix struct를 예로 들어보겠다.

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

위 matrix structure는 2차열 배열과 아주 유사한 구조를 가지고 있고, 각각의 element에 접근하기 위해서 2개의 input parameter를 받는 subscript를 구현하고 있다.






'IOS > Swift' 카테고리의 다른 글

[Swift 4.0] Initialization(1)  (0) 2017.04.01
[Swift 4.0] Inheritance  (0) 2017.04.01
[Swift 4.0] Methods  (0) 2017.04.01
[Swift 4.0] Properties  (0) 2017.04.01
[Swift 4.0] Classes and Structures  (0) 2017.04.01
Posted by 홍성곤
,