What are subscripts in Swift? How to define custom subscripts? Can subscripts accept multiple parameters?
Subscripts in Swift are shortcuts for accessing member elements of collections, lists, or sequences. Through subscripts, you can access and set values using square bracket syntax [] without calling separate methods.
Basic Subscript Syntax:
swiftstruct TimesTable { let multiplier: Int subscript(index: Int) -> Int { return multiplier * index } } let threeTimesTable = TimesTable(multiplier: 3) print(threeTimesTable[6]) // 18
Subscript Characteristics:
- Defined using the
subscriptkeyword - Can accept one or more parameters
- Can be read-write, read-only, or write-only
- Can have variadic parameters
- Can have default parameter values
- Can throw errors
Read-Only Subscript:
swiftstruct 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 { return grid[(row * columns) + column] } } }
Read-Write Subscript:
swiftstruct Matrix { let rows: Int let columns: Int var grid: [Double] subscript(row: Int, column: Int) -> Double { get { return grid[(row * columns) + column] } set { grid[(row * columns) + column] = newValue } } } var matrix = Matrix(rows: 2, columns: 2) matrix[0, 0] = 1.0 matrix[0, 1] = 2.0 print(matrix[0, 0]) // 1.0
Subscripts with Multiple Parameters:
swiftstruct Chessboard { var board: [[String]] = Array(repeating: Array(repeating: "", count: 8), count: 8) subscript(row: Int, column: Int) -> String { get { return board[row][column] } set { board[row][column] = newValue } } subscript(position: String) -> String { get { let column = position[position.startIndex] let row = Int(position.dropFirst())! return board[row][columnToIndex(column)] } set { let column = position[position.startIndex] let row = Int(position.dropFirst())! board[row][columnToIndex(column)] = newValue } } private func columnToIndex(_ column: Character) -> Int { return Int(column.asciiValue! - Character("a").asciiValue!) } } var chessboard = Chessboard() chessboard["a1"] = "Rook" chessboard[0, 0] = "Queen"
Type Subscript:
swiftenum Planet: Int { case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune static subscript(n: Int) -> Planet? { return Planet(rawValue: n) } } let mars = Planet[4]
Subscript with Default Parameters:
swiftstruct DefaultSubscript { var values: [Int] = [] subscript(index: Int, default defaultValue: Int = 0) -> Int { get { return index < values.count ? values[index] : defaultValue } set { if index < values.count { values[index] = newValue } else { values.append(newValue) } } } }
Best Practices:
- Use subscripts to provide concise access syntax
- Reasonably design subscript parameters for readability
- Provide multi-parameter subscripts for multidimensional data
- Be aware of the performance impact of subscripts
- Consider using methods instead of subscripts in complex scenarios