ProgrammazioneSviluppatore iOS

Spiega le caratteristiche del lavoro con Subscripts in Swift. Quali sono le limitazioni per il subscript, come si può estendere questo meccanismo e dove dovrebbe essere applicato? Fornisci un esempio di subscript non standard.

Supera i colloqui con l'assistente IA Hintsage

Risposta

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:

  • Una classe o una struttura possono avere più subscript (sovraccarico per parametri).
  • Il subscript può essere read-only o read-write (contenere solo get o sia get che set).
  • Il subscript può avere qualsiasi numero di parametri e tipi (ad esempio, due indici).
  • Non è supportato il parametro variadico.

Applicazione:

  • Per un accesso semplificato a collezioni, matrici, oggetti personalizzati, valori serializzati, ecc.

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

Domanda ingannevole

Può un subscript avere un parametro di tipo inout o essere mutating in una struttura?

Risposta:

  • Il parametro del subscript non può essere inout.
  • Il subscript in un tipo valore (struct/enum) può essere dichiarato come 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 } } }

Esempi di errori reali a causa della mancanza di conoscenza delle sottigliezze dell'argomento


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.