Swift - Struct / Class (6_subscript)

이한솔·2023년 9월 8일
0

Swift 문법 🍎

목록 보기
18/32

subscript

클래스, 구조체, 열거형에서 시퀀스의 멤버 요소에 접근하기 위한 바로가기 첨자

// 배열에서 시퀀스 값에 접근할 때 [] 대괄호 안에 index를 넣어줘서 멤버 요소에 접근하는데 이것이 subscript이다.
let nums: [Int] = [1, 2, 3, 4]
 
nums[0] // 1
nums[1] // 2

// swift에 정의되어있는 배열의 [] 정의
@inlinable public subscript(index: Int) -> Element

// Dictionary의 value 접근할 때도 subscript 사용
let dictionary: [String: Int] = ["one": 1, "two": 2]
 
dictionary["one"] // 1
dictionary["two"] // 2

// swift에 정의되어있는 Dictionary의 [] 정의
@inlinable public subscript(key: Key) -> Value?

💡 왜 서브스크립트를 호출할 당시 (index: ), [key: ]로 호출하지 않는지?
일반 메소드라면 외부 매개변수로 호출해야하지만 subscipt는 파라미터 선언 당시 외부 매개변수를 _로 쓰지않아도 외부 매개변수로 사용되지 않는다.

subscript 정의 방법

단일 타입에 여러 서브스크립트를 정의할 수 있다. subscript 키워드로 작성하며 하나 이상의 파라미터와 반환 값을 지정한다. 파라미터나 리턴형을 생략할 수 없고, gettersetter 모두 구현할 수 있다. setter는 생략가능하지만 getter는 생략 불가능하다.

// 서브스크립트 정의는 마치 연산 프로퍼티와 비슷하다.
// setter의 경우 파라미터를 생략하면 newValue로 접근할 수 있고 get-only일 경우 `get`을 생략 가능한 것도 연산 프로퍼티와 같다.
subscript(index: Int) -> Int {
    get {
    }
    set(newValue) {
    }
}

// 원래 swift에서 string은 배열처럼 string[index]로 접근 불가능하다.
// subscript를 통해 직접 정의해주면 사용 가능하다.
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 string = "Hello, Swift!"
print(string[0]) // 출력값: Optional("H")
print(string[100]) //출력값: nil


struct Stack {
    var stack: [Int] = [0, 1, 2, 3, 4, 5]
 
    subscript(index: Int) -> Int {
        get {
            return stack[index]
        }
        set {
            stack[index] = newValue
        }
    }
}

var stack = Stack()

// getter 접근 
print(stack[0])   

// setter 접근
stack[1] = 9
print(stack[1]) // 출력값: 9


타입 subscript

오버라이딩이 불가하다면 static / 가능하다면 class로 선언해주면 타입 subscript이 된다.

struct Stack2 {
    static var stack: [Int] = [0, 1, 2, 3]
 
    static subscript(index: Int) -> Int {
        return stack[index]
    }
}

// 인스턴스 없이 타입 이름으로 호출이 가능하다.
print(Stack2[0]) // 출력값: 0


출처: https://babbab2.tistory.com/123

0개의 댓글