我在大约4个月前在Swift开始了一个新的iOS项目,只是为了学习这门语言。虽然我一直在开发它,但我发现自己几乎从未在整个程序中使用元组。这是因为我真的习惯了没有元组的Java和Objective-C。
我听说过一些关于元组的好东西,Apple似乎非常兴奋将它们添加到Swift中,但似乎我很难找到一个非常有用的案例。
到目前为止,我理解并使用它们:快速类替代品。而不是为了保持一些属性的唯一目的而创建一个新类,而是使用元组代替。但即便如此,我也只使用过一次元组,因为很多时候这些属性会相互影响,因此那些改变这些属性的方法最好包含在具有这些属性的类中。这真的是一个优势吗?
但在OOP(或Swift)中使用的其他一些非常有用的设计模式是什么?对元组不熟悉的人应该知道什么?
谢谢!
答案 0 :(得分:4)
标准库中的几个例子可能会有所帮助。
一个常见的需求是不仅从函数返回一个值,而且返回两个不同的值。例如,在_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
结构就是字典作为其元素的结构,那么这也会增加复杂性,可能会妨碍理解字典的工作方式。
显然,这是一种权衡,如果你在任何地方使用元组而不是定义适当的结构,那么你将走得太远而使你的代码变得不可读。但是在使用一次性和轻量级的情况下,它们更容易编写并且更易于阅读。
答案 1 :(得分:3)
switch
语句一起使用时有用的元组。例如:
let point = (x: 10, y: 5)
switch point {
case (10, 5):
println("Point at (10, 5)")
case (-10...10, 5):
println("Point where y = 5 and x lies in the range [-10, 10]")
case (_, 5) :
println("Point with y = 5")
case (let x, _) where x % 2 == 0:
println("Point with x that is a multiple of 2 (x = \(x))")
default:
println("A Point")
}
显然,这不是你真正使用的那种例子,但我认为它展示了元组的一些功能。
Apple的 Swift编程语言讨论了有关元组的更多信息,如果你还没有看到它,请点击链接:https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-ID309