클래스, 구조체, 열거형에서 시퀀스의 멤버 요소에 접근하기 위한 바로가기 첨자로,
단일 타입에 여러 서브스크립트를 정의할 때 사용한다.
배열을 사용하면서 배열 내의 element에 접근할 때 사용한다.
let nums: [Int] = [1, 2, 3, 4]
nums[0] // 1
nums[1] // 2
" [ ] " 대괄호 안에 index를 통해 배열 내의 element에 접근하는데
이게 바로 서브스크립트이다.
서브스크립트 정의문법
서브스크립트 정의 문법은 연산 프로퍼티와 비슷하다.
getter / setter 모두 구현 가능하고, get only는 되지만, set only는 불가능하다.
subscript(index: Int) -> Int {
get {
}
set(newValue) {
}
}
String 타입의 변수 안에 값을 하나 선언하고,
이를 배열 처럼 " [ ] " 를 통해 각 요소별로 접근하고 싶다면?
let appleSubscript = "hello, apple!!"
appleSubscript[0] // Error!
"h"가 반환되면 좋지만, 실제로는 Error가 발생한다.
따라서 String 타입을 확장해서 서브스크립트를 직접 작성해주면 된다.
일단 subscript(idx: Int)를 통해 Int 타입의 파라미터를 받아서 String 타입으로 반환한다.
guard ~ else 문을 통해 파라미터로 들어온 Int 타입의 값이 범위 내에 있는지 확인하다.
target 이라는 상수를 선언하고 그 안에 index 값을 넣는다.
그리고 String 타입의 값으로 변환해서 반환한다.
extension String {
subscript(idx: Int) -> String? {
guard (0..<count).contains(idx) else {
return nil
}
let target = index(startIndex, offsetBy: idx)
return String(self[target])
}
}
다시 서브스크립트를 직접 구현해주면 된다.
let appleSubscript = "hello, apple!!"
appleSubscript[0] // Optional("H")
서브스크립트 예제
struct Stack {
var stack: [Int] = [0, 1, 2, 3, 4, 5]
subscript(index: Int) -> Int {
get {
return stack[index]
}
set {
stack[index] = newValue
}
}
}
위와 같이 구조체에 서브스크립트를 구현했을 때
" [ ] " 를 통해 getter / setter에 접근할 수 있다.
var stack: Stack = .init()
stack[0] // 서브스크립트 getter 접근
stack[1] = 2 // 서브스크립트 setter 접근
타입 서브스크립트
오버라이딩이 불가능하다 ➡ "static"
오버라이딩이 가능하다 ➡ "class"
인스턴스 생성할 필요 없이, "타입 이름"으로 호출할 수 있게 된다.
struct Stack {
static var stack: [Int] = [0, 1, 2, 3]
static subscript(index: Int) -> Int {
return stack[index]
}
}
Stack[0] // 0
Stack[1] // 1
'Swift > 기본' 카테고리의 다른 글
메모리 구조 (Code, Data, Stack, Heap) (1) | 2024.04.18 |
---|---|
접근 제어자 (Access Control) (0) | 2024.04.17 |
제네릭 (제네릭 제약, 제네릭 확장, 제네릭 함수와 오버로딩) (0) | 2024.04.16 |
제네릭 (0) | 2024.04.15 |
고차함수 (0) | 2024.04.15 |