Historia pytania:
Subscript został wprowadzony w Swift, aby ułatwić i bezpiecznie pracować z kolekcjami i strukturami danych, pozwalając na dostęp do elementów za pomocą znajomej składni nawiasów kwadratowych.
Problem:
Zamieszanie między subscript, metodami a właściwościami obliczonymi, ich zakresem zastosowania, a także błędne użycie subscript do uzyskiwania dostępu do danych, które nie są kolekcjami lub mają efekt uboczny.
Rozwiązanie:
Subscript to specjalny mechanizm, który pozwala na dostęp do elementów obiektu za pomocą nawiasów kwadratowych. Może być tylko do odczytu lub do odczytu i zapisu i obsługuje parametry dowolnego typu: nie tylko Int, ale również String lub własne typy.
Przykład kodu:
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
Kluczowe cechy:
Czy subscript może mieć więcej niż jeden parametr?
Tak, subscript może przyjmować dowolny zestaw parametrów i dowolnego typu (np. krotka).
Przykład kodu:
// Zobacz przykład powyżej z Matrix, gdzie subscript(row: Int, column: Int)
Czy można zaimplementować subscript tylko do odczytu (read-only)?
Tak, jeśli nie zadeklarujesz set, subscript będzie tylko do odczytu.
Przykład kodu:
struct ReadOnlyArray { private let items = [1, 2, 3] subscript(index: Int) -> Int { return items[index] } }
Jaka jest różnica między subscript a właściwością obliczoną?
Właściwość obliczona zawsze ma stałą nazwę i nie przyjmuje parametrów. Subscript pozwala na dostęp za pomocą zmiennego indeksu, naśladując strukturę kolekcji.
W niestandardowej strukturze subscript jest używany do zmiany globalnego stanu, co powoduje nieoczekiwane efekty uboczne przy prostym uzyskiwaniu dostępu do elementu w tablicy.
Zalety:
Wady:
Subscript jest używany tylko do pracy z prywatną tablicą wewnątrz struktury, zaimplementowano obsługę przekroczenia granic z zwracaniem nil.
Zalety:
Wady: