Background:
Subscript was introduced in Swift for convenient and safe working with collections and data structures, allowing access to elements using the familiar square bracket syntax.
Problem:
Confusion between subscripts, methods, and computed properties, their scope of application, and mistakenly using subscripts to access data that are not collections or have side effects.
Solution:
Subscript is a special mechanism that provides access to elements of an object using square brackets. It can be read-only or read-write and supports parameters of any kind: not only Int but also String or custom types.
Code example:
struct Matrix { private var data: [[Int]] init(rows: Int, columns: Int) { data = Array(repeating: Array(repeating: 0, count: columns), count: rows) } subscript(row: Int, column: Int) -> Int { get { data[row][column] } set { data[row][column] = newValue } } } var matrix = Matrix(rows: 2, columns: 2) matrix[0, 1] = 5 print(matrix[0, 1]) // 5
Key features:
Can a subscript have more than one parameter?
Yes, a subscript can take any set of parameters of any type (e.g., tuple).
Code example:
// See the example above with Matrix, where subscript(row: Int, column: Int)
Can a subscript be read-only?
Yes, if the set is not declared, the subscript will be read-only.
Code example:
struct ReadOnlyArray { private let items = [1, 2, 3] subscript(index: Int) -> Int { return items[index] } }
What is the difference between a subscript and a computed property?
A computed property always has a fixed name and does not take parameters. A subscript allows access by a variable index, mimicking a collection structure.
In a custom structure, a subscript is used to change global state, causing unexpected side effects when simply accessing an element in an array.
Pros:
Cons:
A subscript is used only for working with a private array within the structure, handling out-of-bounds access by returning nil.
Pros:
Cons: