Subscripts

Classes, structures, and enumerations can define subscripts, which are shortcuts for accessing the member elements of a collection, list, or sequence. You use subscripts to set and retrieve values by index without needing separate methods for setting and retrieval. For example, you access elements in an Array instance as someArray[index] and elements in a Dictionary instance as someDictionary[key]

You can define multiple subscripts for a single type, and the appropriate subscript overload to use is selected based on the type of index value you pass to the subscript. Subscripts are not limited to a single dimension, and you can define subscripts with multiple input parameters to suit your custom type’s needs. 

(array나 dictionary처럼 index,key를 통해 element에 접근가능하게 하는 방법 제공한다는 이야기 그러나 꼭 index,key (string) 형식이 아니어도 상관없음)

Subscript Syntax

Subscripts enable you to query instances of a type by writing one or more values in square brackets after the instance name. Their syntax is similar to both instance method syntax and computed property syntax. You write subscript definitions with the subscript keyword, and specify one or more input parameters and a return type, in the same way as instance methods. Unlike instance methods, subscripts can be read-write or read-only. This behavior is communicated by a getter and setter in the same way as for computed properties:

subscript(index: Int) -> Int {
   get {
       // return an appropriate subscript value here
   }
   set(newValue) {
       // perform a suitable setting action here
   }
}

The type of newValue is the same as the return value of the subscript. As with computed properties, you can choose not to specify the setter’s (newValue) parameter. A default parameter called newValue is provided to your setter if you do not provide one yourself.

As with read-only computed properties, you can simplify the declaration of a read-only subscript by removing the get keyword and its braces:

subscript(index: Int) -> Int {
   // return an appropriate subscript value here
}

example of a read-only subscript implementation

struct TimesTable {
   let multiplier: Int
   subscript(index: Int) -> Int {
       return multiplier * index
   }
}
let threeTimesTable = TimesTable(multiplier: 3)
print(“six times three is (threeTimesTable[6])”)
// Prints “six times three is 18”

Subscript Usage

Subscripts are typically used as a shortcut for accessing the member elements in a collection, list, or sequence. You are free to implement subscripts in the most appropriate way for your particular class or structure’s functionality.

For example, Swift’s Dictionary type 

var numberOfLegs = [“spider”: 8, “ant”: 6, “cat”: 4]
numberOfLegs[“bird”] = 2

Subscript Options

Subscripts can take any number of input parameters, and these input parameters can be of any type. Subscripts can also return any type. Subscripts can use variadic parameters(정해지지 않은 수의 변수 즉 여러개의 parameters), but they can’t use in-out parameters(값을 받고 계산된 값을 되돌리는 경우) or provide default parameter values.

A class or structure can provide as many subscript implementations as it needs, and the appropriate subscript to be used will be inferred based on the types of the value or values that are contained within the subscript brackets at the point that the subscript is used. This definition of multiple subscripts is known as subscript overloading.

While it is most common for a subscript to take a single parameter, you can also define a subscript with multiple parameters if it is appropriate for your type. The following example defines a Matrix structure, which represents a two-dimensional matrix of Double values. The Matrix structure’s subscript takes two integer parameters:

struct Matrix {
   let rows: Int, columns: Int
   var grid: [Double]
   init(rows: Int, columns: Int) {
       self.rows = rows
       self.columns = columns

       // 첫번째 파라미터는 값, 두번째 파라미터는 array 요소의 갯수

       // 참조 

Creating an Array with a Default Value.

       grid = Array(repeating: 0.0, count: rows * columns)
   }
   func indexIsValid(row: Int, column: Int) -> Bool {
       return row >= 0 && row < rows && column >= 0 && column < columns
   }
   subscript(row: Int, column: Int) -> Double {
       get {
           assert(indexIsValid(row: row, column: column), “Index out of range”)
           return grid[(row * columns) + column]
       }
       set {
           assert(indexIsValid(row: row, column: column), “Index out of range”)
           grid[(row * columns) + column] = newValue
       }
   }
}

var matrix = Matrix(rows: 2, columns: 2)

matrix[0, 1] = 1.5
matrix[1, 0] = 3.2

func indexIsValid(row: Int, column: Int) -> Bool {
   return row >= 0 && row < rows && column >= 0 && column < columns
}

let someValue = matrix[2, 2]
// this triggers an assert, because [2, 2] is outside of the matrix bounds

Comments are closed.

Post Navigation