我正在浏览快速教程,并且遇到了一些示例,这些示例实现了诸如Sequence,有时是Collection,有时是Iterator的协议
我查看了何时真正使用此协议,但从未找到。所有其他材料都说明了如何使用它,但没有说明何时使用。
有人可以建议我在哪里可以学到这个。任何快速提示都将真正有帮助。
谢谢
答案 0 :(得分:2)
为特定类型(例如Array
)编写例程通常是最简单的,但是例如,为Sequence
协议编写它们可以提供更大的灵活性。在编写集合扩展时,我通常会遇到这种情况,根据定义,扩展可以在其他地方重用,并且灵活性具有最大的价值。
例如,考虑此Array
扩展名来求和:
extension Array where Element == Int {
func sum() -> Int {
var sum = 0
for element in self {
sum += element
}
return sum
}
}
如果您确实有一个数组,例如,
let total = [1, 2, 3].sum() // fine
但是,如果您有范围,那将不起作用,例如:
let total = (1...3).sum() // this won’t work
您必须将其转换为数组才能工作:
let total = Array(1...3).sum() // this will work, but introduces a little syntactic noise
但是,您可以将扩展名定义为Array
,而不是将其定义为Sequence
扩展名:
extension Sequence where Element == Int {
func sum() -> Int {
var sum = 0
for element in self {
sum += element
}
return sum
}
}
看起来几乎一样,但是此表示法适用于任何序列(例如,数组和范围),例如:
let total1 = [1, 2, 3].sum() // this is still fine ...
let total2 = (1...3).sum() // but now, this now works as intended, too
还有一些我可能更喜欢特定类型协议的示例:
在编写接受字符串输入的例程时,我可能会将其编写为接受StringProtocol
,以便该例程同时接受字符串和子字符串(例如string[start..<end]
)。
在处理范围时,我采用了类似的思维过程,理想情况下,算法应在封闭范围,开放范围,部分范围等条件下工作。在需要一定灵活性的情况下,我将使用RangeExpression
,而我在寻找快速简单的内容时只会使用Range
。
在编写方法时,最重要的是,请问自己,该方法仅适用于Array
类型是否很重要,或者是否有其他顺序可以使用同一例程。
就我何时为自己的类型使用Sequence
或迭代器而言,这种情况很少见。我将在编写真正的“序列”时执行此操作,在此情况下,下一个值是根据之前的值生成的,例如斐波那契数列或此count-and-say sequence。您可以在调用点与序列进行一些非常自然的交互,而不必将结果塞入数组。但是,在现实应用程序中,我们遇到这种模式的机会几乎没有简单数组那么频繁。