Search
Duplicate

Subscript (서브스크립트)

생성일
2023/11/20 14:07
태그
Grammar

 Subscript (서브스크립트)

 서브스크립트

 클래스, 구조체, 열거형에서 시퀀스의 멤버 요소에 접근하기 위한 바로가기 첨자로, 단일 타입에 여러 서브스크립트를 정의할 수 있다.
우리는 계속 자연스럽게 서브스크립트를 써왔다.
대표적으로 우리가 배열을 사용하면서 원소에 값에 접근할 때,
let nums: [Int] = [1, 2, 3, 4] nums[0] // 1 nums[1] // 2
Swift
복사
이렇게 [] 대괄호 안에 index를 넣어줘서 멤버 요소에 접근을 한다.
이것이 바로 서브스크립트 이다.
 [ ]의 정의
@inlinable public subscript(index: Int) -> Element
Swift
복사
배열의 서브스크립트는 parameter로 Int형을 index로 받고,
해당 index에 해당하는 Element를 반환하는 형태라는 것을 알 수 있다.
let dict: [String: Int] = ["one": 1, "two": 2] dict["one"] // 1 dict["two"] // 2
Swift
복사
딕셔너리에서 Value에 접근할 때, 이렇게 [] 대괄호 안에 Key 값을 넣어줘서 Value에 접근한다.
이것이 바로 서브스크립트이다.
@inlinable public subscript(key: Key) -> Value?
Swift
복사
딕셔너리의 서브스크립트는 Parameter로 Key를 받고, 해당 Key에 해당하는 Value를 반환하는 형태라는 것을 알 수 있다.
→ 이것을 보고 서브스크립트가 어떤 것인지 알 수 있다.

 서브스크립트 정의하기

subscript 키워드로 작성하며 하나 이상의 파라미터와 반환 값을 지정한다.
파라미터나 리턴형을 생략할 수 없고, getter와 setter 모두 구현할 수 있다.
get-only는 가능하지만, set-only는 불가하다 (getter 생략불가)
subscript(index: Int) -> Int { get { } set(newValue) { } }
Swift
복사
서브스크립트 정의는 위와 같은 방식으로 하는데, 마치 연산 프로퍼티와 비슷하고 실제로 연산 프로퍼티와 get/set의 성질은 거의 비슷하다.
setter의 경우, 파라미터를 생략하면 newValue로 접근할 수 있는 것 또한 같고, get-only일 경우 get 구문 생략 가능한 것도 같다
다른 예제로,
String도 배열처럼 [index]로 접근하고 싶다면?
let hj = "Hello, hj!" hj[0] // error!!
Swift
복사
이 에러는 해당 서브스크립트를 사용할 수 없다는 에러이다.
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]) } }
Swift
복사
위와같이 extension을 통해 서브스크립트를 직접 구현해주면,
let hj = "Hello, hj!" hj[0] // Optional("H") hj[100] // nil
Swift
복사
이렇게 [] 을 통해 내가 원하는 index의 문자에 접근할 수 있다.
이것이 바로 서브스크립트 이다.

 만약 Argument Label을 사용하고 싶다면

서브스크립트는 파라미터 선언 당시 Argument Label을 _ 로 처리해주지 않아도, Argument Label로 사용되지 않는다.
Only Parameter Name
subscript(index: Int) -> Int { get { } set(newValue) { } }
Swift
복사

 서브스크립트 사용하기

struct Stack { var stack: [Int] = [0, 1, 2, 3, 4, 5] subscript(index: Int) -> Int { get { return stack[index] } set { stack[index] = newValue } } }
Swift
복사
만약 Stack 이란 구조체에 서브스크립트를 위처럼 구현했을 경우,
var stack: Stack = .init() stack[0] // 서브스크립트 getter 접근 stack[1] = 2 // 서브스크립트 setter 접근
Swift
복사
이렇게 [] 를 통해 getter/setter에 접근할 수 있다.

 타입 서브스크립트 (Type Subscript)

서브스크립트 또한 타입 서브스크립트로 선언이 가능하다.
struct Stack { static var stack: [Int] = [0, 1, 2, 3] static subscript(index: Int) -> Int { return stack[index] } }
Swift
복사
이렇게 오버라이딩이 불가하다면 static
가능하다면 class 로 선언해주면, 타입스크립트가 되는 것이다.
Stack[0] // 0 Stack[1] // 1
Swift
복사
실제로, 인스턴스 없이 ‘타입 이름’에 대고 호출이 가능하다.

 Reference