我听说过一些关于元组的好东西,Apple似乎非常兴奋将它们添加到Swift中,但似乎我很难找到一个真正有用的案例.
到目前为止,我理解并使用它们:快速级替换器.而不是为了保持一些属性的唯一目的而创建一个新类,而是使用元组代替.但即便如此,我也只使用过一次元组,因为很多时候这些属性会相互影响,因此那些改变这些属性的方法最好包含在具有这些属性的类中.这真的是一个优势吗?
但是在OOP(或Swift)中使用的其他一些非常有用的设计模式是什么,那些对元组不熟悉的人应该知道呢?
谢谢!
标准库中的几个示例可能会有所帮助.常见的需求是不仅从函数返回一个值,而且返回两个不同的值.例如,在_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!") }
如果没有元组,您将不得不求助于其中一个结果,或返回另一个结构.
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结构是字典作为其元素保存的结构,那么这也会增加一个复杂性,可能会妨碍理解字典的工作方式.
显然,这是一种权衡,如果你在任何地方都使用元组而不是定义适当的结构,那么你将走得太远而使你的代码变得不可读.但是在使用一次性和轻量级的情况下,它们更容易编写并且更易于阅读.