oop - 一般而言,Swift 或 OOP 中元组的一些典型用例是什么?

标签 oop swift design-patterns tuples object-oriented-analysis

大约 4 个月前我开始了一个新的 iOS 项目,只是为了学习这门语言。在我开发它的过程中,我发现自己几乎从不在整个程序中使用元组。这是因为我真的习惯了没有元组的 Java 和 Objective-C。

我听说过一些关于元组的很棒的事情,Apple 似乎对将它们添加到 Swift 中感到非常兴奋,但我似乎很难为它们找到一个真正有用的案例。

到目前为止,我理解并将它们用于一件事:快速类替代品。不要仅仅为了将几个属性保持在一起而创建一个新类,而是使用一个元组。但即便如此,我也只为此使用了一次元组,因为很多时候这些属性会相互影响,所以那些改变这些属性的方法最好包含在具有这些属性的类中。那么这真的是优势吗?

但不熟悉元组的人应该了解哪些其他真正有用的 OOP(或 Swift)设计模式?

谢谢!

最佳答案

标准库中的几个示例可能会有所帮助。

一个常见的需求是从函数返回的不仅仅是一个值,而是两个不同的值。因此,例如,在 _IntegerArithmeticType 协议(protocol)中,有:

static func addWithOverflow(lhs: Self, _ rhs: Self) -> (Self, overflow: Bool)

也就是说,它返回新值,加上是否存在溢出的 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 结构作为其元素,那也会增加复杂性,可能会妨碍理解字典的工作原理。

显然,这是一种权衡,如果你在任何地方都使用元组而不是定义适当的结构,你就会走得太远,让你的代码难以阅读。但在使用一次性且轻量级的情况下,它们更易于编写和阅读。

关于oop - 一般而言,Swift 或 OOP 中元组的一些典型用例是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29683851/

相关文章:

c++ - 多个 DLL 的问题

python - 在 Python 中覆盖父类(super class)时跳过参数

c++ - 处理超出范围的索引

swift - 当键盘未显示时调用 KeyboardDidShow

swift - 如何修复被阻挡的 View 过渡到增强现实 View

ruby-on-rails - Rails Way 处理多条路线上可用的 Action

java - 哪种设计模式最适合根据某些条件定义多个数据转换器?

dart - 从扩展类访问抽象类属性

java - 如何创建具有关联值(如 Swift 枚举)的 Java 枚举?

javascript - 使用事件在 View 设计模式之间进行通信