Achtergrond van de vraag:
Subscript is een mechanisme voor het verkrijgen van waarden binnen collecties, structs en andere types met behulp van vierkante haakjes. Het is toegevoegd aan Swift naar analogie van andere talen (zoals indexering in Python-lijsten, de operator [] in C++/Java), om de interactie met collecties en dergelijke objecten intuïtiever te maken.
Probleem:
Niet alle types ondersteunen standaard indextoegang zoals arrays. Wanneer we een struct of klasse hebben met gegevens, is het vaak logischer om toegang tot elementen te implementeren via de gebruikelijke syntaxis (zoals myObject[index]), in plaats van via een methode.
Oplossing:
Swift staat toe om subscript zelf te implementeren voor elke gebruikersdefinieerde type. Het kan zowel lees- als schrijfbaar zijn. Bijvoorbeeld — een struct die een subscript implementeert voor het werken met een vierkante matrix:
struct Matrix { let size: Int private var grid: [Int] init(size: Int) { self.size = size self.grid = Array(repeating: 0, count: size * size) } subscript(row: Int, column: Int) -> Int { get { precondition(indexIsValid(row, column), "Index buiten bereik") return grid[(row * size) + column] } set { precondition(indexIsValid(row, column), "Index buiten bereik") grid[(row * size) + column] = newValue } } private func indexIsValid(_ row: Int, _ column: Int) -> Bool { return row >= 0 && row < size && column >= 0 && column < size } } var m = Matrix(size: 3) m[1,2] = 7 print(m[1,2]) // 7
Belangrijkste kenmerken:
Kunnen subscripts alleen voor verzamelingen worden gebruikt?
Nee, subscripts kunnen voor elke type worden geïmplementeerd: struct, klasse, enum. Het datatype binnen hoeft niet per se een verzameling te zijn, het belangrijkste is de logica voor het verwerken van aanvragen via subscript.
Is het mogelijk om meerdere subscripts met verschillende handtekeningen in één type te maken?
Ja, het is toegestaan om subscripts met verschillende parameterhandtekeningen te overbelasten:
struct Example { subscript(index: Int) -> Int { return index } subscript(key: String) -> String { return key.uppercased() } }
Is het toegestaan om subscript als computed property zonder set te gebruiken?
Ja, subscript kan alleen voor lezen zijn (get-only), waarbij de poging tot schrijven een compileerfout zal veroorzaken.
struct ReadOnly { subscript(index: Int) -> Int { index * index } }
In een grote struct is een subscript geïmplementeerd zonder bereikcontrole, wat leidt tot een crash van de applicatie bij een ongeldige index.
Voordelen:
Nadelen:
Matrix is geïmplementeerd met precondition voor het indexbereik. Elke fout wordt onmiddellijk opgevangen en komt niet in productie.
Voordelen:
Nadelen: