티스토리 뷰
서브스크립트 (Subscripts)
클래스, 구조체, 열거형에서 스크립트를 정의해 사용할 수 있습니다.
서브스크립트를 활용하면 추가적인 메소드 없이 특정 값을 할당하거나 가져올 수 있습니다.
예를들어, Array 인스턴스의 특정 요소에 someArray[index] 문법으로,
Dictionary 인스턴스의 특정 요소에 someDictionary[key] 이런식으로 접근할수 있습니다.
하나의 타입으로 여러 서브스크립트를 정의할 수 있으며, 오버로드(Overload)도 가능합니다. (질문)
또한 필요에 따라 여러 인자 값을 사용할 수 있습니다.
서브스크립트 문법 (Subscripts Syntax)
인스턴스 메소드 문법과 연산 프로퍼티 문법과 유사합니다.
다만, 서브스크립트에선 읽기-쓰기(read-write) 또는 읽기전용이 (read only) 가능 합니다.
// 1
subscript(index: Int) -> Int {
// 2
get {
// 반환 값
}
set(newValue) {
// set 액션
}
}
1. subscript 키워드를 사용하여 정의를하고,
2. getter와 setter 방식을 따릅니다.
• 연산 프로퍼티와 같이 setter에 파라미터를 따로 명시해주지 않으면 기본값으로 newValue를 사용합니다.
읽기전용 연산 프로퍼티 같이, get, set을 키워드를 사용하지 않음으로써 간단하게 getter (읽기전용) 서브스크립트를 정의할 수 있습니다.
subscript(index: Int) -> Int {
// 반환 값
}
다음은 읽기전용 서브스크립트의 예제 입니다.
struct TimeTable {
let multiplier: Int
subscript(index: Int) -> Int {
return multiplier * index
}
}
let threeTimesTable = TimeTable(multiplier: 3)
print("six times three is \(threeTimesTable[6])")
// six times three is 18
multiplier를 3으로 받는 TimeTable구조체를 인스턴스화 한 threeTimesTable에 [6] 이라는 인덱스(index)를 넣어줌으로써,
subscript 구문에 index = 6, multiplier = 3 을 넣어줌으로써, 둘을 곱한 값 18이 출력 됩니다.
서브스크립트 사용 (Subscripts Usage)
'subscript' 는 사용되는 문맥에 따라 달라집니다.
일반적으로 collection, list, sequence의 멤버 요소에 쉽게 액세스하기 위한 용도로 사용됩니다.
Swift의 사전(Dictionary) 타입에서 서브스크립트의 사용 예제를 봅시다.
var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
numberOfLegs["bird"] = 2
print(numberOfLegs)
// ["cat": 4, "ant": 6, "spider": 8, "bird": 2]
numberOfLegs는 타입추론에 의해 [String: Int] 타입을 갖고,
두번째 줄 numberOfLegs["bird"] = 2 numberOfLegs의 key 값에 "bird", value 값에 2 를 넣습니다.
NOTE
사전(Dictionary) 타입은 모든 key에 값이 없을 수도 있다는 사실을 모델링하고,
key에 nil 값을 할당하여 key에 대한 값을 삭제할 수 있는 방법을 제공합니다.
서브스크립트 옵션 (Subscripts Options)
서브스크립트는 파라미터에 어떤 숫자던, 어떤 타입이던, 어떤 반환 값이던 제한이 없습니다.
함수와 다른점은 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, 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
}
}
}
구조체 Matrix는 rows와 columns 두개의 파라미터를 받으며, Double 타입의 rows * columns 값을 저장할 수 있을 만큼 충분히 큰 배열을 만듭니다.
행렬의 각 포지션에는 초기값 0.0 이 지정됩니다.
아래와 같이 초기값을 지정해 보겠습니다.
var matrix = Matirx(rows: 2, columns: 2)
rows: 2, columns: 2를 갖는 새로운 Matrix인스턴스를 만들어서 단조롭게 된 버전의 matrix 입니다.
matrix 내부의 값을 서브스크립트로 콤마 ( , )를 이용해 row와 column 값을 넣어줄 수 있습니다.
matrix[0, 1] = 1.5 // 0번째 row, 1번째 column에 1.5를 넣음
matrix[1, 0] = 3.2 // 1번째 row, 0번째 column에 3.2를 넣음
즉 아래와 같이 입력이 됩니다.
행렬의 입출력시 row/column의 범위가 적절한지는 indexIsValid(row,column) 메소드에서 확인합니다.
func indexIsValid(row: Int, column: Int) -> Bool {
return row >= 0 && row < rows && column >= 0 && column < columns
}
만약 적절한 범위를 벗어나면 assertion(assert)이 실행됩니다.
let someValue = matrix[2, 2]
// 위의 matirx의 사용범위는 [1, 1] 까지
// [2, 2]가 사용할 수 있는 행렬의 범위를 벗어나므로 assert가 실행됨
타입 서브스크립트 (Type Subscripts)
서브스크립트 자체에 타입을 지정할 수 있는데 이를 타입 서브스크립트 라고 합니다.
static 키워드를 사용하여 타입 서브스크립트라는걸 나타낼 수 있고,
클래스에선 class 키워드를 사용하여 하위클래스가 상위 클래스를 상속받아 override(재정의)할 수 있습니다.
아래는 타입 서브스크립트이 예제 입니다.
enum Planet: Int {
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
static subscript(n: Int) -> Planet { // static 키워드 사용 (타입 서브스크립트)
return Planet(rawValue: n)!
}
}
let mars = Planet[4]
print(Planet[2])
print(mars)
static 을 사용하여 타입 서브스크립트인걸 알 수 있으며,
인스턴스를 만들 필요없이 바로 Planet[4]에 접근하여 상수 mars에 값을 넣어준걸 확인할 수 있습니다.
오늘은 서브스크립트에 대해 알아보았는데요.
아직까지는 어디에 써야 적합할지 짐작이 가질 않네요 ㅠ
일단 이런게 있구나 정도로만 이해를 하고 넘어가고
추후 여러 코드들을 보면서 좋은 예제가 있다면 추가 포스팅 하겠습니다 :)
'iOS' 카테고리의 다른 글
[iOS] 메모리 구조 (memory) (0) | 2022.04.06 |
---|---|
[iOS] LaunchScreen 설정 후 디바이스에만 나오지 않을때 (0) | 2022.04.05 |
[iOS] UserDefaults 로 객체를 저장을 해보자 (0) | 2022.03.30 |
[iOS] URLSession (0) | 2022.03.27 |
[iOS] .contentMode (scaleToFill / scaleAspectFit / scaleAspectFill) (0) | 2022.03.25 |
- Total
- Today
- Yesterday
- swift (programmers)
- Swift 알고리즘
- CS 네트워크
- Swift
- Swift init
- 2023년 회고
- removeLast()
- Swift RIBs
- Swift 내림차순
- Swift Error Handling
- Swift 프로그래머스
- swift protocol
- Swift 프로퍼티
- Swift final
- Swift joined
- Swift inout
- RTCCameraVideoCapturer
- Combine: Asynchronous Programming with Swift
- Swift Leetcode
- swift programmers
- Swift ModernRIBs
- ios
- Class
- swift reduce
- swift 고차함수
- swift property
- iOS error
- Swift joined()
- 원티드 프리온보딩
- RIBs tutorial
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |