Subscripts in Swift consentono di fornire accesso ai valori di un tipo tramite una chiave o un indice in modo simile a array o dizionari, ma per i propri tipi. La sintassi è simile a quella di una funzione, ma l'accesso avviene tra parentesi: object[key].
Caratteristiche:
get o sia get che set).Applicazione:
Esempio: Matrice bidimensionale e subscript con due parametri:
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), "Indice fuori dal range") return grid[(row * columns) + column] } set { precondition(isValid(row: row, column: column), "Indice fuori dal 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
Può un subscript avere un parametro di tipo inout o essere mutating in una struttura?
Risposta:
inout.mutating set, il che consente di modificare self all'interno di set:struct Counter { var value: Int = 0 subscript(increment: Bool) -> Int { mutating get { value += increment ? 1 : -1 return value } } }
Storia
In una collezione personalizzata, si è dimenticato di fare set nel subscript mutating nella struttura, di conseguenza qualsiasi tentativo di modificare un elemento tramite subscript ha generato un errore di compilazione. L'errore si è manifestato nella fase di integrazione della collezione dopo una lunga fase di debug.
Storia
Nel subscript personalizzato non è stata implementata una corretta gestione dell'uscita dai confini dell'indice, il che ha causato crash durante l'accesso al di fuori dell'intervallo. Di conseguenza, sono crollate funzioni critiche per il business di elaborazione dei dati.
Storia
È stato implementato un subscript con due parametri in un enum per la memorizzazione nella cache, ma non si è tenuto conto che il subscript non può essere statico (nel tipo), ma solo nell'istanza. La soluzione architetturale si è rivelata errata, è stato necessario riscrivere l'API di interazione con la collezione.