Видеокурсы по изучению языка программирования Swift. Подробнее

Опции индекса

Если вы нашли опечатку в тексте, выделите ее и нажмите CTRL + ENTER.

Индексы могут принимать любое количество входных параметров, и эти параметры могут быть любого типа. Индексы так же могут возвращать любой тип. Индексы могут использовать вариативные параметры, но они не могут иметь сквозных параметров или обеспечивать исходные значения параметрам.

Класс или структура могут обеспечить столько индексных реализаций, сколько нужно, и подходящий индекс, который будет использоваться, будет выведен, основываясь на типе значения или значений, которые содержаться внутри индексных скобок, в том месте, где этот индекс используется. Определение множественных индексов так же известно как перегрузка индекса.

Сейчас в большинстве случаев индекс принимает один единственный параметр, вы так же можете определить индекс с несколькими параметрами, если этот вариант подходит для вашего типа. Следующий пример определяет структуру Matrix, которая представляет собой двухмерную матрицу значений типа Double. Индекс структура Matrix принимает два целочисленных параметра.

struct Matrix {
   let rows: Int, columns: Int
   var grid: [Double]
   init(rows: Int, columns: Int) {
      self.rows = rows
      self.columns = columns
      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
      }
   }
}

Matrix предоставляет инициализатор, который принимает два параметра rows и columns, и создает массив типа Double, который имеет размер rows * columns. Каждой позиции в матрице дается начальное значение 0.0. Чтобы этого достичь, размер массива и начальное значение клетки равное 0.0 передаются в инициализатор массива, который создает и инициализирует новый массив необходимого размера. Это описано подробнее в главе Создание и инициализация массива.

Вы можете создать новый экземпляр типа Matrix, передав количество рядов и столбцов в его инициализатор:

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

Этот пример создает новый экземпляр Matrix, который имеет всего два ряда и два столбца. Массив grid для экземпляра Matrix фактически упрощенный вариант версии матрицы, который читается с левой верхней части в правую нижнюю часть:

Значения в матрице могут быть установлены через передачу значений ряда и столбца в индексе, разделенных между собой запятой:

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

Эти два выражения в сеттере индекса устанавливают значения 1.5 для верхней правой позиции (где row равен 0, column равен 1), и значение 3.2 для нижней левой позиции (где row равен 1, а column равен 0 ):

Геттер и сеттер индекса Matrix оба содержат утверждения для проверки валидности значений row и column. Для помощи утверждениям, Matrix имеет удобный метод под названием indexIsValidFor(row:column:), который проверяет наличие запрашиваемых row, column в существующей матрице:

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

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

let someValue = matrix[2, 2]
//это вызывает утверждение, потому что [2, 2] находится за пределами матрицы
Swift: 
3.0