Search

[Swift 공식 문서] 12. SubScripts

Subscripts

아래의 항목에 대해서 subscript 사용이 가능합니다.
Class
Strucutre
Enumeration
서브스크립트를 사용하면 해당 타입의 요소에 인덱스로 접근 및 수정이 가능해집니다.
하나의 타입에 여러개의 서브 스크립트를 정의가능합니다.
이러한 경우 index 의 유형에 따라 서브 스크립트를 자동으로 추론합니다

Syntax

인스턴스 이름 뒤에 [] 붙여서 데이터에 접근 가능
서브 스크립트는 읽기 - 쓰기 또는 읽기 전용으로 정의되어야 합니다.

읽기 - 쓰기

getter setter 구문을 통해 구현
subscript(index: Int) -> Int { get { // Return an appropriate subscript value here. } set(newValue) { // Perform a suitable setting action here. } }
Swift
복사
newValue 는 setter 구문의 디폴트 매개변수이므로 명시하지 않아도 된다.

읽기 전용

subscript(index: Int) -> Int { // Return an appropriate subscript value here. }
Swift
복사
get 키워드 사용하지 않아도 된다.

실제 예제

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"
Swift
복사
인덱스를 활용해서 타입의 요소에 접근하는 모습이다.

Subscript Usage

서브 스크립트의 의미는 맥락에 따라 다른데, 일반적으로는 컬렉션의 원소에 빠르게 접근하는 데 사용된다.
var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4] numberOfLegs["bird"] = 2 // 첨자 접근을 활용해 딕셔너리에 새로운값을 빠르게 추가하는 모습
Swift
복사
꼭 이렇게 사용하는 해야하는 것은 아니다.
사용자의 의도에 맞게 적절하게 커스텀해주어도 된다.

Subscript Options

서브 스크립트에는 여러개의 파라미터를 정의할 수 있으며, 이러한 파라미터는 어떠한 타입이든 상관없다. 또한 서브 스크립트는 어떠한 타입의 값이든 리턴이 가능하다
함수 처럼 서브스크립트는 다수의 파라미터를 받아 파라미터에 초기값을 건네줄 수 있다.
또한 가변(Variadic) 인자 또한 사용이가능하다.
단, in-out 매개변수는 사용이 불가능하다.
필요한 만큼 다수의 서브스크립트를 정의할 수 있다. 인덱스로 전달된 값의 타입을 기반으로 적절한 서브스크립트를 추론한다. 따라서 이들의 중복은 신경쓸 필요 없다.
또한 다수의 서브스크립트를 정의하는 것을 subscript overloading 이라고 한다.
서브스크립트는 보통 하나의 파라미터만을 가지지만, 여러개도 가능하다.
아래는 여러개의 파라미터를 가지는 서브스크립트의 예제이다.
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 } } }
Swift
복사
grid 는 1차원 배열이지만,
서브스크립트를 통해 우리는 논리적으로 이차행렬을 다룰 수 있게 된다.
matrix[0, 1] = 1.5 matrix[1, 0] = 3.2
Swift
복사
또한 아래의 코드처럼 함수를 정의해 서브스크립트의 파라미터에 올바른 값이 전달되었는지 점검할 수도 있다.
func indexIsValid(row: Int, column: Int) -> Bool { return row >= 0 && row < rows && column >= 0 && column < columns }
Swift
복사
아래의 코드는 assertion 을 발생시킨다. (잘못된 첨자 접근)
let someValue = matrix[2, 2] // This triggers an assert, because [2, 2] is outside of the matrix bounds.
Swift
복사

Type Subscripts

여타 다른 프로퍼티들 처럼 static 키워드를 사용해 타입 서브스크립트를 정의할 수 도 있다.
해당 서브스크립트는 타입 자체로부터 호출이 가능하다.
class 에서는 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)
Swift
복사