Сабскрипты


Классы, структуры и перечисления могут определять сабскрипты (subscripts). Сабскрипты используются для доступа к элементам коллекции или последовательности. В ряде языков программирования есть похожая концепция - индексаторы. Сабскрипты позволяют обращаться с объектом класса или структуры как с отдельной коллекцией.

Для определения сабскрипта используется ключевое слово subscript:

1
2
3
4
5
6
7
8
9
10
11
subscript(параметры) -> тип_возвращаемых_объектов {

get {

// возвращаем значение
}
set(newValue) {

// устанавливаем новое значение newValue
}
}
После ключевого слова subscript в скобках идут параметры, которые используются для получения элементов. Нередко параметры представляют числовой индекс, по которому надо получить объект. Далее указывается тип элементов, с которыми мы работаем.

Сабскрипт может состоять из двух блоков: get и set. Блок get возвращает элемент, а блок set устанавливает новое значение, которое передается через параметр newValue.

Например, создадим класс библиотеки. Упрощенно библиотека представляет некоторый набор книг. То есть мы можем представить класс библиотеки как коллекцию книг и использовать сабскрипты для получения книг по индексу:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Book{ // класс книги

var name: String
init(name: String){

self.name = name
}
}
class Library{ // класс библиотеки

var books: [Book] = [Book]()

init(){

books.append(Book(name: "Война и мир"))
books.append(Book(name: "Отцы и дети"))
books.append(Book(name: "Чайка"))
}

subscript(index: Int) -> Book{

get{
return books[index]
}
set(newValue){
books[index] = newValue
}
}
}

var myLibrary: Library = Library()
var firstBook: Book = myLibrary[0] // получаем элемент по индексу 0
print(firstBook.name) // Война и мир

myLibrary[2] = Book(name: "Мартин Иден") // установка элемента по индексу 2
print(myLibrary[2].name) // Мартин Иден
Здесь сабскрипт предназначен для работы с типом Book. В блоке get происходит получение объекта Book по индексу из массива books. В блоке set устанавливаем объект Book в массиве books.

В итоге в программе мы сможем обращаться к библиотеке как к массиву по индексу для получения нужной книги:

1
var firstBook: Book = myLibrary[0]
Есть два типа сабскриптов:

Сабскрипты, которые поддерживают чтение и запись (то есть с блоками get и set, как в примере выше)

Сабскрипты только для чтения (только с блоком get)

Изменим класс библиотеки, чтобы применить сабскрипт только для чтения:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Library{

var books: [Book] = [Book]()

init(){

books.append(Book(name: "Война и мир"))
books.append(Book(name: "Отцы и дети"))
books.append(Book(name: "Чайка"))
}

subscript(index: Int) -> Book{

return books[index]
}
}