斯威夫特 2.2 -> 3.0:Strideable
:s stride(...)
替换为全局stride(...)
功能
在 Swift 2.2 中,我们可以(正如您在自己的尝试中尝试过的那样)使用蓝图(和默认实现的)函数stride(through:by:)
and stride(to:by:)
从协议Strideable
/* Swift 2.2: stride example usage */
let from = 0
let to = 10
let through = 10
let by = 1
for _ in from.stride(through, by: by) { } // from ... through (steps: 'by')
for _ in from.stride(to, by: by) { } // from ..< to (steps: 'by')
而在 Swift 3.0 中,这两个函数已被删除Strideable
赞成全局函数stride(from:through:by:) and stride(from:to:by:);因此上面的等效 Swift 3.0 版本如下
/* Swift 3.0: stride example usage */
let from = 0
let to = 10
let through = 10
let by = 1
for _ in stride(from: from, through: through, by: by) { }
for _ in stride(from: from, to: to, by: by) { }
在您的示例中,您想使用闭区间步幅替代方案stride(from:through:by:)
,因为你的不变量for
循环使用与 less 的比较或等于 (<=
). I.e.
/* example values of your parameters 'first', 'last' and 'interval' */
let first = 0
let last = 10
let interval = 2
var n = 0
for f in stride(from: first, through: last, by: interval) {
print(f)
n += 1
} // 0 2 4 6 8 10
print(n) // 6
我们自然会在哪里使用您的for
循环仅作为段落的示例for
循环到stride
,对于您的具体示例,您自然可以计算n
不需要循环(n=1+(last-first)/interval
).
Swift 3.0:替代方案stride
对于更复杂的迭代增量逻辑
With 进化提案SE-0094的实施、Swift 3.0引入全球sequence
功能:
-
sequence(first:next:),
-
sequence(state:next:),
这可以是一个适当的替代方案stride
对于具有更复杂迭代增量关系的情况(本例中不是这种情况)。
声明
func sequence<T>(first: T, next: @escaping (T) -> T?) ->
UnfoldSequence<T, (T?, Bool)>
func sequence<T, State>(state: State,
next: @escaping (inout State) -> T?) ->
UnfoldSequence<T, State>
我们将简要介绍这两个函数中的第一个。这next
参数采用一个闭包,该闭包应用一些逻辑来延迟构造给定当前序列元素的下一个序列元素(从first
)。当以下情况时,序列终止next
回报nil
,或无穷大,如果next
一去不复返nil
.
应用于上面的简单恒定步长示例,sequence
方法有点冗长和矫枉过正。适合此目的的stride
解决方案:
let first = 0
let last = 10
let interval = 2
var n = 0
for f in sequence(first: first,
next: { $0 + interval <= last ? $0 + interval : nil }) {
print(f)
n += 1
} // 0 2 4 6 8 10
print(n) // 6
The sequence
然而,对于步幅不恒定的情况,函数变得非常有用,例如如以下问答中所涵盖的示例所示:
- 在 swift 中表达具有动态范围的 for 循环
只需注意用最终的终止序列nil
return (如果不是:“无限”元素生成),或者,当 Swift 3.1 到来时,结合使用其惰性生成prefix(while:)
序列方法,如进化提案中所述SE-0045。后者应用于该答案的运行示例使得sequence
方法不太冗长,明确包括元素生成的终止标准。
/* for Swift 3.1 */
// ... as above
for f in sequence(first: first, next: { $0 + interval })
.prefix(while: { $0 <= last }) {
print(f)
n += 1
} // 0 2 4 6 8 10
print(n) // 6