Особенности Swift, Часть 2: Кортежи

Кортежи в Swift

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

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

var result = (200, "OK", true)

В данном примере result - это кортеж который хранит в себе число 200, строку "OK" и логическое значение true. Для того, чтобы объявить кортеж без присвоения ему значений, можно просто поместить типы значений в круглые скобки:

  1. var result: (Int, String, Bool)
  2. result = (200, "OK", true)

Получение доступа к элементам кортежа

Существуют два способа доступа к элементам кортежа: через указывание индекса элемента после имени переменной кортежа, и через разложение кортежа. Рассмотрим эти два способа.

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

  1. var result = (200, "OK", true)
  2. result.0 // => 200

Так как кортеж мы объявили как переменную, мы также можем менять значение элементов кортежа таким способом.

  1. var result = (200, "OK", true)
  2. result.0 // => 200
  3. result.0 = 400
  4. result = (400, "OK", true)

Соответственно если мы бы объявили result как константу, то мы бы не смогли поменять значения его элементов.

Следующий способ получения доступа к элементам кортежа - его разложение:

  1. var result = (200, "OK", true)
  2. var (statusCode, statusMessage, hasBody) = result

Здесь, мы в первой строчке создали кортеж с тремя элементами. Во второй строчке мы написали, что хотим разложить элементы кортежа result, по трем переменным statusCode, statusMessage и hasBody. Теперь переменным statusCode, statusMessage и hasBody будут присвоены значения 200, "OK" и true соответственно.

То же самое мы могли написать и в виде констант, например:

let (statusCode, statusMessage, hasBody) = result

Тогда, значения statusCode, statusMessage и hasBody нельзя было бы изменить.

Если по какой-то причине мы не хотим получать доступ к каким либо элементам, мы можем их исключить с помощью знака нижнего подстрочия "_" :

let (_ , _ , hasBody) = result

Именование элементов кортежа

Элементам кортежа в Swift можно давать имена. То есть пример кортежа выше мы могли написать так:

var result = (statusCode: 200, statusMessage: "OK", hasBody: true)

В этому случае мы бы могли получать доступ к элементам через указание имени элемента, а не индекса:

result.statusCode // => 200

Такая конструкция похожа на то, что result является объектом какого-то класса, а statusCode - это свойство этого класса. Да, действительно, мы обладаем теми же возможностями что и со свойствами классов. Apple рекомендует в таких случаях задумываться о масштабе объекта. Например, если мы хотим создать какой-нибудь временный объект, то лучше всего использовать кортеж с его именованными параметрами. А если нам нужен большой объект, с многочисленными свойствами и методами, то нам лучше использовать классы или структуры.

Где используются кортежи?

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

  1. var a = 1
  2. var b = 2
  3. var c = 3

мы можем записать в одну строку:

var (a, b, c) = (1, 2, 3) 

Еще одно применение кортежей - в циклах for...in. Например, если у нас есть словарь cityTemp, в котором содержатся значения температуры в нескольких городах :

var cityTemp = ["Moscow": 6, "NewYork": 4, "London": 2, "Los Angeles": 22]

Мы можем пройтись по элементам этого словаря с помощью цикла for...in:

  1. for (cityName, temp) in cityTemp {
  2.  println("Температура в городе \(cityName) сейчас равняется \(temp) градуса Цельсия")
  3. }

Этот код напечатает нам температуру в каждом городе.

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

  1. func getTempInSaratov() -> ( String , Int ) {
  2.  return ("Saratov", 13)
  3. }

Здесь мы просто указали, что возвращаемое значение функции будет кортеж с элементами типа String и Int. Если функция возвращает кортеж, то мы его можем разложить:

  1. let (city,temp) = getTempInSaratov()
  2.  println("Температура в городе \(city) сейчас равняется \(temp) градуса Цельсия")

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

var tempInSaratov = getTempInSaratov()

Теперь давайте сделаем элементы кортежа именованными. Нам просто нужно элементам возвращающих значений функции приписать имена:

  1. func getTempInSaratov() -> ( city: String , temp: Int ) {
  2.  return ("Saratov", 13)
  3. }
  4. var tempInSaratov = getTempInSaratov()
  5.  println("Температура в городе \(tempInSaratov.city) сейчас равняется \(tempInSaratov.temp) градуса Цельсия")

Если вам понравилась статья или вы хотите задать вопрос, напишите об этом в комментарии.