Может помочь пара примеров из стандартной библиотеки.
Распространенной потребностью является возврат не одного значения функции, а двух разных значений. Так, например, в протоколе _IntegerArithmeticType
есть:
static func addWithOverflow(lhs: Self, _ rhs: Self) -> (Self, overflow: Bool)
То есть он возвращает новое значение плюс логический индикатор того, было ли переполнение:
let i: UInt8 = 0xFF
let (j, overflow) = UInt8.addWithOverflow(i, 1)
if overflow { println("Oh noes!") }
Без кортежа вам пришлось бы прибегнуть к inout
для одного из результатов или вернуть другую структуру.
Коллекция Dictionary
содержит два типа элементов: ключ и значение. Они часто связаны вместе, поэтому Dictionary
определяет тип, Element
как кортеж из двух:
struct Dictionary<Key : Hashable, Value> : CollectionType, DictionaryLiteralConvertible {
typealias Element = (Key, Value)
}
Затем, когда вы перебираете словарь, каждый элемент, который вы получаете, представляет собой эту пару, а встроенная деструктуризация кортежей позволяет вам удобно разделить их на два:
// either treat them as a pair:
for element in myDictionary { }
// or destructure them:
for (k, v) in myDictionary { }
Теоретически оба этих примера можно было бы реализовать, определив новые структуры. Так, например, в случае переполнения:
struct ResultWithOverflow<T: _IntegerArithmeticType> {
let value: T
let overflow: Bool
}
static func addWithOverflow(lhs: Self, _ rhs: Self) -> ResultWithOverflow<Self>
Однако важно понимать, что здесь кортежи используются не просто потому, что определение этой дополнительной структуры утомительно (хотя это и правда). Это больше потому, что эта дополнительная структура беспорядочна — она мешает чтению функции. Если вы хотите знать, что сделал addWithOverflow
, вам нужно найти, что такое ResultWithOverflow
. Вместо этого с кортежем в определении функции совершенно ясно, что возвращается.
Точно так же, если бы существовала структура DictionaryElement
, которую словарь содержал в качестве своего элемента, это также было бы дополнительным усложнением, которое могло бы помешать пониманию того, как работают словари.
Очевидно, что это компромисс, и если вы везде будете использовать кортежи вместо определения правильных структур, вы зайдете слишком далеко и сделаете свой код нечитаемым. Но в тех случаях, когда использование одноразовое и легковесное, их и легче писать, и понятнее читать.
person
Airspeed Velocity
schedule
16.04.2015