ProgrammatieiOS developer

Leg de bijzonderheden uit van het werken met Subscripts in Swift. Welke beperkingen zijn er voor subscript, hoe kan dit mechanisme worden uitgebreid en waar moet het worden toegepast? Geef een voorbeeld van een niet-standaard subscript.

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord

Subscripts in Swift maken het mogelijk om toegang te verlenen tot waarden van een type op basis van een sleutel of index, vergelijkbaar met arrays of dictionaries, maar voor elk van onze eigen types. De syntaxis lijkt op een functie, maar toegang vindt plaats in haakjes: object[key].

Bijzonderheden:

  • Een klasse of structuur kan meerdere subscripts hebben (overloading op parameters).
  • Subscript kan read-only of read-write zijn (alleen get, of get en set).
  • Subscript kan een willekeurig aantal parameters en types hebben (bijvoorbeeld twee indexen).
  • Geen ondersteuning voor variadic parameters.

Toepassing:

  • Voor vereenvoudigde toegang tot collecties, matrices, custom-objecten, serializeerbare waarden, enz.

Voorbeeld: Een tweedimensionale array (matrix) en subscript met twee parameters:

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

Bedrogachtige vraag

Kan subscript een parameter van het type inout hebben of mutating zijn in een structuur?

Antwoord:

  • De parameter van subscript kan niet inout zijn.
  • Subscript in value type (struct/enum) kan worden gedeclareerd als mutating set, wat het mogelijk maakt om self binnen set te wijzigen:
struct Counter { var value: Int = 0 subscript(increment: Bool) -> Int { mutating get { value += increment ? 1 : -1 return value } } }

Voorbeelden van echte fouten door onbekendheid met de subtiliteiten van het onderwerp


Verhaal

In een custom collectie was vergeten om set in subscript mutating te maken in de structuur, waardoor elke poging om een element via subscript te wijzigen een compilatiefout veroorzaakte. De fout kwam aan het licht tijdens de integratiefase van de collectie na langdurige debugging.


Verhaal

In een custom subscript werd geen correcte afhandeling van indexuitloop gerealiseerd, wat crashes veroorzaakte bij toegang buiten het bereik. Hierdoor vielen bedrijfskritieke functies voor gegevensverwerking uit.


Verhaal

Er werd een subscript met twee parameters in een enum gerealiseerd voor caching, maar men had niet in aanmerking genomen dat subscript niet static (bij het type) kan zijn, maar alleen bij de instantie. De architecturale oplossing bleek foutief te zijn, waardoor de API-interactie van de collectie herschreven moest worden.