ProgrammierungiOS Entwickler

Erklären Sie die Besonderheiten der Arbeit mit Subscripts in Swift. Welche Einschränkungen gibt es für Subscript, wie kann dieser Mechanismus erweitert werden und wo sollte er angewendet werden? Geben Sie ein Beispiel für ein nicht standardmäßiges Subscript.

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort

Subscripts in Swift ermöglichen den Zugriff auf Werte eines Typs über einen Schlüssel oder Index, ähnlich wie bei Arrays oder Dictionaries, jedoch für beliebige eigene Typen. Die Syntax ähnelt einer Funktion, aber der Zugriff erfolgt in Klammern: object[key].

Besonderheiten:

  • Eine Klasse oder Struktur kann mehrere Subscripts haben (Überladung nach Parametern).
  • Subscript kann read-only oder read-write sein (entweder get oder sowohl get als auch set enthalten).
  • Subscript kann beliebig viele Parameter und Typen haben (zum Beispiel zwei Indizes).
  • Es gibt keine Unterstützung für variadische Parameter.

Anwendung:

  • Für den vereinfachten Zugriff auf Sammlungen, Matrizen, benutzerdefinierte Objekte, serialisierbare Werte usw.

Beispiel: Zweidimensionales Array (Matrix) und Subscript mit zwei Parametern:

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 außerhalb des Bereichs") return grid[(row * columns) + column] } set { precondition(isValid(row: row, column: column), "Index außerhalb des Bereichs") 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

Fangfrage

Kann ein Subscript einen Parameter vom Typ inout haben oder in einer Struktur mutating sein?

Antwort:

  • Der Parameter eines Subscript kann nicht inout sein.
  • Ein Subscript in einem Werttyp (struct/enum) kann als mutating set deklariert werden, was es ermöglicht, self innerhalb von set zu ändern:
struct Counter { var value: Int = 0 subscript(increment: Bool) -> Int { mutating get { value += increment ? 1 : -1 return value } } }

Beispiele für reale Fehler aufgrund von Unkenntnis der Feinheiten des Themas


Geschichte

In einer benutzerdefinierten Sammlung wurde vergessen, set im Subscript in der Struktur mutating zu machen, weshalb jeder Versuch, ein Element über das Subscript zu ändern, einen Kompilierungsfehler verursachte. Der Fehler trat in der Integrationsphase der Sammlung nach langer Fehlersuche auf.


Geschichte

In einem benutzerdefinierten Subscript wurde die korrekte Behandlung des Überschreitens des Indexbereichs nicht implementiert, was zu Abstürzen beim Zugriff außerhalb des Bereichs führte. Infolgedessen fielen geschäftskritische Datenverarbeitungsfunktionen aus.


Geschichte

Ein Subscript mit zwei Parametern wurde für ein Enum zur Caching-Implementierung erstellt, jedoch wurde nicht berücksichtigt, dass Subscript nicht static (vom Typ) sein kann, sondern nur für die Instanz. Die architektonische Lösung stellte sich als fehlerhaft heraus, und die API-Interaktion der Sammlung musste neu geschrieben werden.