Subscripts

Groot·2022년 8월 24일
0

Swift Language Guide

목록 보기
12/24
post-thumbnail

Subscripts

  • class, struct 및 열거형은 컬렉션, 목록 또는 시퀀스의 구성원 요소에 액세스하기 위한 바로 가기인 첨자를 정의할 수 있습니다.
  • 첨자를 사용하여 설정 및 검색을 위한 별도의 방법 없이 인덱스별로 값을 설정하고 검색합니다.
  • 예를 들어 Array 인스턴스의 요소에 someArray[index]로 액세스하고 Dictionary 인스턴스의 요소에 someDictionary[key]로 액세스합니다.
  • 단일 유형에 대해 여러 첨자를 정의할 수 있으며, 사용할 적절한 첨자 오버로드는 첨자에 전달하는 인덱스 값의 유형에 따라 선택됩니다.
  • 첨자는 단일 차원으로 제한되지 않으며 사용자 정의 유형의 요구에 맞게 여러 입력 매개변수로 첨자를 정의할 수 있습니다.

📌 Subscript Syntax

  • 첨자를 사용하면 인스턴스 이름 뒤에 대괄호 안에 하나 이상의 값을 작성하여 유형의 인스턴스를 쿼리할 수 있습니다.
  • 해당 구문은 인스턴스 메서드 구문 및 계산된 속성 구문과 유사합니다.
  • subscript 키워드를 사용하여 아래 첨자 정의를 작성하고 인스턴스 메서드와 동일한 방식으로 하나 이상의 입력 매개변수와 반환 유형을 지정합니다.
  • 인스턴스 메서드와 달리 아래 첨자는 읽기-쓰기 또는 읽기 전용일 수 있습니다. 이 동작은 계산된 속성과 동일한 방식으로 getter 및 setter에 의해 전달됩니다.
    subscript(index: Int) -> Int {
        get {
            // Return an appropriate subscript value here.
        }
        set(newValue) {
            // Perform a suitable setting action here.
        }
    }
  • newValue의 유형은 아래 첨자의 반환 값과 동일합니다.
  • 계산된 속성과 마찬가지로 setter의 (newValue) 매개변수를 지정하지 않도록 선택할 수 있습니다.
  • newValue라는 기본 매개변수는 직접 제공하지 않으면 setter에 제공됩니다.
  • 읽기 전용 계산 속성과 마찬가지로 get 키워드와 중괄호를 제거하여 읽기 전용 첨자의 선언을 단순화할 수 있습니다.
    subscript(index: Int) -> Int {
        // Return an appropriate subscript value here.
    }
  • 다음은 정수의 n배 테이블을 나타내는 TimesTable struct를 정의하는 읽기 전용 첨자 구현의 예입니다.
    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"
  • 이 예에서 TimesTable의 새 인스턴스는 3번 테이블을 나타내기 위해 생성됩니다.
  • 이는 인스턴스의 승수 매개변수에 사용할 값으로 struct체의 이니셜라이저에 값 3을 전달하여 표시됩니다.
  • threeTimesTable[6] 호출에서 볼 수 있는 것처럼 아래 첨자를 호출하여 threeTimesTable 인스턴스를 쿼리할 수 있습니다.
  • 이것은 18 또는 3 곱하기 6의 값을 반환하는 three-times-table의 여섯 번째 항목을 요청합니다.

    n-times-table은 고정된 수학 규칙을 기반으로 합니다. threeTimesTable[someIndex]를 새 값으로 설정하는 것은 적절하지 않으므로 TimesTable의 첨자는 읽기 전용 첨자로 정의됩니다.

📌 Subscript Usage

  • "아래 첨자"의 정확한 의미는 사용되는 컨텍스트에 따라 다릅니다.
  • 첨자는 일반적으로 컬렉션, 목록 또는 시퀀스의 멤버 요소에 액세스하기 위한 바로 가기로 사용됩니다.
  • 특정 class나 struct체의 기능에 가장 적절한 방식으로 첨자를 자유롭게 구현할 수 있습니다.
  • 예를 들어, Swift의 Dictionary 유형은 Dictionary 인스턴스에 저장된 값을 설정하고 검색하기 위해 아래 첨자를 구현합니다.
  • 아래 첨자 괄호 안에 사전의 키 유형 키를 제공하고 사전의 값 유형 값을 아래 첨자에 할당하여 사전에 값을 설정할 수 있습니다.
    var numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
    numberOfLegs["bird"] = 2
  • 위의 예는 numberOfLegs라는 변수를 정의하고 세 개의 키-값 쌍을 포함하는 사전 리터럴로 초기화합니다.
  • numberOfLegs 사전의 유형은 [String: Int]로 유추됩니다.
  • 사전을 생성한 후 이 예제는 "bird"의 String 키와 2의 Int 값을 사전에 추가하기 위해 아래 첨자 할당을 사용합니다.

    Swift의 사전 유형은 키-값 첨자를 선택적인 유형을 취하고 반환하는 첨자로 구현합니다. 위의 numberOfLegs 사전의 경우 키-값 첨자는 Int? 또는 "선택적 int" 유형의 값을 취하여 반환합니다. 사전 유형은 선택적 첨자 유형을 사용하여 모든 키에 값이 있는 것은 아니라는 사실을 모델링하고 해당 키에 nil 값을 할당하여 키에 대한 값을 삭제할 수 있는 방법을 제공합니다.

📌 Subscript Options

  • 첨자는 여러 입력 매개변수를 사용할 수 있으며 이러한 입력 매개변수는 모든 유형이 될 수 있습니다.
  • 첨자는 또한 모든 유형의 값을 반환할 수 있습니다.
  • 함수와 마찬가지로 첨자는 가변 매개변수 및 기본 매개변수 값에 설명된 대로 다양한 수의 매개변수를 사용하고 매개변수에 대한 기본값을 제공할 수 있습니다.
  • 그러나 함수와 달리 아래 첨자는 in-out 매개변수를 사용할 수 없습니다.
  • class 또는 struct는 필요한 만큼의 첨자 구현을 제공할 수 있습니다.
  • 그리고 사용되는 적절한 아래 첨자는 아래 첨자가 사용되는 지점에서 아래 첨자 괄호 안에 포함된 값 또는 값의 유형을 기반으로 유추됩니다.
  • 여러 첨자에 대한 이러한 정의를 첨자 오버로딩이라고 합니다.
  • 아래 첨자가 단일 매개변수를 사용하는 것이 가장 일반적이지만 유형에 적합한 경우 여러 매개변수로 아래 첨자를 정의할 수도 있습니다.
  • 다음 예제에서는 Double 값의 2차원 행렬을 나타내는 Matrix struct를 정의합니다.
  • Matrix struct의 아래 첨자는 두 개의 정수 매개변수를 사용합니다.
    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
            }
        }
    }
  • Matrix는 행과 열이라는 두 개의 매개변수를 사용하는 이니셜라이저를 제공하고 Double 유형의 행 * 열 값을 저장할 수 있을 만큼 충분히 큰 배열을 만듭니다.
  • 행렬의 각 위치에는 초기 값 0.0이 지정됩니다. 이를 위해 배열의 크기와 초기 셀 값 0.0이 올바른 크기의 새 배열을 생성하고 초기화하는 배열 이니셜라이저에 전달됩니다.
  • 적절한 행과 열 수를 초기화 프로그램에 전달하여 새 Matrix 인스턴스를 구성할 수 있습니다.
    var matrix = Matrix(rows: 2, columns: 2)
  • 위의 예에서는 2개의 행과 2개의 열이 있는 새 Matrix 인스턴스를 만듭니다.
  • 이 Matrix 인스턴스에 대한 그리드 배열은 왼쪽 위에서 오른쪽 아래로 읽을 때 효과적으로 행렬의 병합된 버전입니다.
  • 행렬의 값은 행과 열 값을 쉼표로 구분하여 아래 첨자로 전달하여 설정할 수 있습니다.
    matrix[0, 1] = 1.5
    matrix[1, 0] = 3.2
  • 이 두 명령문은 아래 첨자의 setter를 호출하여 행렬의 오른쪽 상단 위치(행은 0, 열은 1)에 값을 1.5로 설정하고 왼쪽 하단 위치(행은 1, 열은 0)에 3.2를 설정합니다.
  • Matrix 첨자의 getter와 setter에는 모두 첨자의 행과 열 값이 유효한지 확인하는 어설션이 포함되어 있습니다.
  • 이러한 주장을 지원하기 위해 Matrix에는 indexIsValid(row:column:)라는 편리한 메서드가 포함되어 있습니다. 이 메서드는 요청된 행과 열이 행렬의 경계 안에 있는지 확인합니다.
    func indexIsValid(row: Int, column: Int) -> Bool {
        return row >= 0 && row < rows && column >= 0 && column < columns
    }
  • 행렬 경계 밖에 있는 아래 첨자에 액세스하려고 하면 어설션이 트리거됩니다.
    let someValue = matrix[2, 2]
    // This triggers an assert, because [2, 2] is outside of the matrix bounds.

📌 Type Subscripts

  • 위에서 설명한 대로 인스턴스 첨자는 특정 유형의 인스턴스에서 호출하는 첨자입니다.
  • 유형 자체에서 호출되는 첨자를 정의할 수도 있습니다. 이러한 종류의 첨자를 유형 첨자라고 합니다.
  • 아래 첨자 키워드 앞에 정적 키워드를 작성하여 유형 아래 첨자를 나타냅니다.
  • class는 대신 class 키워드를 사용하여 하위 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)
profile
I Am Groot

0개의 댓글