Het subscript mechanisme in Swift is geïntroduceerd met de taal in 2014 en is bedoeld voor een gemakkelijker toegang tot gegevens in collecties met een meer beknopte syntaxis. Subscripts maakt het mogelijk om toegang te krijgen tot elementen van arrays, dictionaries en andere collecties via vierkante haken. Modern Swift staat het toe om eigen subscripts te creëren voor eigen types, waardoor de API intuïtief aanvoelt, vergelijkbaar met de standaard datastructuren.
Probleem: Eerder waren de toegangsmethoden omslachtiger (bijvoorbeeld via .getElement(at:)), terwijl subscript de interactie met het type beknopter maakt. Een onjuiste implementatie kan echter leiden tot suboptimale code of fouten bij toegang buiten de collectie.
Oplossing: Voor de implementatie van subscript wordt het sleutelwoord subscript gebruikt, gevolgd door de parameters en het terug te geven waarde. Subscript kan alleen-lezen of zowel lezen als schrijven zijn. Bovendien kunnen subscripts worden overbelast voor verschillende parameters.
Voorbeeldcode:
struct Matrix { let rows: Int let columns: Int var grid: [Double] init(rows: Int, columns: Int) { self.rows = rows self.columns = columns self.grid = Array(repeating: 0.0, count: rows * columns) } subscript(row: Int, column: Int) -> Double { get { assert(row >= 0 && row < rows && column >= 0 && column < columns, "Index out of range") return grid[(row * columns) + column] } set { assert(row >= 0 && row < rows && column >= 0 && column < columns, "Index out of range") grid[(row * columns) + column] = newValue } } } var matrix = Matrix(rows: 2, columns: 2) matrix[0, 1] = 3.14 print(matrix[0, 1]) // 3.14
Belangrijke kenmerken:
Kun je subscript alleen-lezen maken? Of moet subscript altijd get en set zijn?
Subscript kan alleen-lezen zijn (alleen get) als set ontbreekt in de implementatie. Het is niet verplicht om beide accessor-methoden te implementeren, wat vergelijkbaar is met properties.
Voorbeeldcode:
subscript(index: Int) -> Int { get { return index * 2 } }
Kun je wijzigbare parameters doorgeven via inout in subscript?
Nee, subscript ondersteunt geen inout-parameters in de handtekening. Alle parameters van subscripts worden binnen het lichaam van de accessoren als let-constanten behandeld.
Kunnen subscripts een optioneel type retourneren?
Ja, subscripts kunnen optionele waarden retourneren, wat handig is voor veilige toegang tot elementen van een collectie zonder risico op index out of range.
Voorbeeldcode:
extension Array { subscript(safe index: Int) -> Element? { return indices.contains(index) ? self[index] : nil } }
Implementatie van subscript zonder validatie voor uitbuitingen voor een samengesteld type matrix, wat leidt tot crashes van de applicatie bij index fouten.
Voordelen:
Nadelen:
Een optionele versie van subscript toegevoegd voor veilige indexering en foutafhandeling, wat de API duidelijker en veiliger maakt.
Voordelen:
Nadelen: