转载

关于 stride 与循环结构

stride 是 Strideable 协议中定义的一个方法, 它可以按照指定的递进值生成一个序列。可以用在 Swift 的循环语法结构中。

前面我们一片文章中介绍了 Swift 3.0 删除了 C 风格循环后的几个替代方案, 后来发现还有一个方案忘了跟大家提到, 就是 stride 方法。

stride 方法定义在 Strideable 协议中。 Swift 中的大部分基础类型都实现了这个协议, 比如 Int, Float 等等。

先来看看 stride 方法的定义, 它有两种形式:

func stride(through end: Self, by stride: Self.Stride) -> StrideThrough<Self>

func stride(to end: Self, by stride: Self.Stride) -> StrideTo<Self>

一种是 stride through, 另一种是 stride to。 这两个的区别咱们直接上代码来看:

1.stride(through: 5, by: 1)   // 1,2,3,4,5
1.stride(to: 5, by: 1) // 1,2,3,4

这两个调用都是生成一个从 1 到 5 的序列, 使用 through 的方式生成的序列会包含终点值(也就是5)。 使用 to 方法生成的序列不包含终点值。

stride 应用在循环结构中

for i in 1.stride(to: 5, by: 1) {

}

这样就会生成一个从 1 到 4 的遍历序列。 如果我们要遍历的是一个数组,就可以这样:

for i in 0.stride(to: arr.count, by: 1) {

}

这个循环语句从索引 0 开始遍历 arr 这个数组。 那么同样的逻辑还可以用我们之前提到的 range 方法来实现:

for i in 0..<arr.count {

}

从代码上看, 好像这种 range 的方法更加简洁, 那为什么还要用 stride 呢。 那么我们再来看看这种情况:

for i in 0.stride(to: arr.count, by: 3) {

}

这次我们其他地方都没变,只把 by 参数从 1 改到了 3。 这样 stride 生成的索引序列就变成了 0 3 6 9…

stride 相比 range 语法的方式会更加灵活, 我们可以指定索引递增的步长。 总体来说如果一般的顺序遍历,使用 range 语法会更加简单。 如果你的循环逻辑有特殊要求, 那么 stride 可以更好的满足。

注意 stride 方法返回的类型, 分别是 StrideThrough 和 StrideTo, 他们都继承自 SequenceType。 也就是说我们作用于集合类型的方法也可以应用于 stride 生成的序列:

for i in 0.stride(to: arr.count, by: 1).reverse() {

}

对序列使用 reverse 方法,就可以实现反向遍历。

并且 Swift 中除了 Int 类型, 还有很多类型实现了 Strideable 协议。 比如 Double 类型:

let pi = Double(M_PI)
0.0.stride(to: 8 * pi, by: pi)

结尾

stride 方法可以做为我们另外一个循环结构的替代方案。 结合前面说的 range 语法以及 enumeate 方法, 熟悉了时候, 你会不会也发现 C 风格的循环语法有些过时了呢。

原文  http://www.swiftcafe.io/2016/07/20/stride/
正文到此结束
Loading...