프로그래밍iOS 개발자

Swift에서 Subscripts 작업의 특성을 설명하십시오. subscript에 대해 어떤 제한이 있으며, 이 메커니즘을 어떻게 확장할 수 있으며, 어디에 적용해야 합니까? 비표준 subscript의 예를 제시하십시오.

Hintsage AI 어시스턴트로 면접 통과

답변

Subscripts는 Swift에서 배열이나 딕셔너리와 유사하게 키나 인덱스를 통해 타입의 값에 접근할 수 있도록 해 주지만, 사용자 정의 타입에도 사용할 수 있습니다. 구문은 함수와 유사하지만 다음과 같이 괄호 안에서 접근합니다: object[key].

특성:

  • 클래스나 구조체는 여러 개의 subscript를 가질 수 있습니다 (매개변수에 대한 오버로딩).
  • Subscript는 읽기 전용 또는 읽기-쓰기일 수 있습니다 (get만 포함하거나 getset을 모두 포함).
  • Subscript는 임의의 수와 유형의 매개변수를 가질 수 있습니다 (예: 두 개의 인덱스).
  • 가변 매개변수는 지원되지 않습니다.

적용:

  • 컬렉션, 행렬, 사용자 정의 객체, 직렬화 가능한 값 등에 대한 간편한 접근을 위해.

예: 2차원 배열(행렬)과 두 개의 매개변수를 가진 subscript:

struct Matrix { let rows: Int, columns: Int private var grid: [Double] init(rows: Int, columns: Int) { self.rows = rows self.columns = columns grid = Array(repeating: 0.0, count: rows * columns) } subscript(row: Int, column: Int) -> Double { get { precondition(isValid(row: row, column: column), "Index out of range") return grid[(row * columns) + column] } set { precondition(isValid(row: row, column: column), "Index out of range") grid[(row * columns) + column] = newValue } } private func isValid(row: Int, column: Int) -> Bool { return row >= 0 && row < rows && column >= 0 && column < columns } } var matrix = Matrix(rows: 2, columns: 2) matrix[0,1] = 5.0 print(matrix[0,1]) // 5.0

함정 질문

subscript가 inout 유형의 매개변수를 가질 수 있거나 구조체에서 mutating일 수 있습니까?

답변:

  • subscript의 매개변수는 inout일 수 없습니다.
  • 값 타입(struct/enum)에서 subscript는 mutating set으로 선언할 수 있으며, 이를 통해 set 내에서 self를 변경할 수 있습니다:
struct Counter { var value: Int = 0 subscript(increment: Bool) -> Int { mutating get { value += increment ? 1 : -1 return value } } }

주제를 모르고 생기는 실제 오류의 예


이야기

사용자 정의 컬렉션에서 구조체에서 subscript의 set을 mutating으로 만들지 않아, subscript를 통해 요소를 변경하려는 모든 시도가 컴파일 오류를 일으켰습니다. 이 오류는 오랜 디버깅 후 컬렉션 통합 단계에서 나타났습니다.


이야기

사용자 정의 subscript에서 인덱스의 범위를 벗어나는 경우를 올바르게 처리하지 않아 범위를 벗어나는 호출 시 크래시가 발생했습니다. 그 결과 데이터 처리와 관련된 비즈니스 크리티컬한 기능이 중단되었습니다.


이야기

캐싱을 위해 enum에서 두 개의 매개변수를 가진 subscript를 구현했지만, subscript가 타입에 대해 static이 아니라 인스턴스에서만 가능하다는 것을 간과했습니다. 아키텍처 결정이 잘못된 것으로 판명되어 컬렉션 상호 작용 API를 다시 작성해야 했습니다.