Swift 中的 Sequence 基础篇

栏目: Swift · 发布时间: 9年前

内容简介:Swift 中的 Sequence 基础篇

Swift 是一门可以让你按照自己喜欢的方式写代码的语言,它有很强的扩展能力,而它众多的 Collection Protocols 则是这种扩展能力的提供者之一。

本文介绍一下 Sequance 和 Iterator 的基本概念,及如何实现一个 Sequence。

撰写本文时的 Swift 版本是 Swift 3.1。

Sequence

Sequence 是一系列相同类型的值的集合,并且提供对这些值的迭代能力。

迭代一个 Sequence 最常见的方式就是 for-in 循环

for element in someSequence {
    doSomething(with: element)
}

Sequence Protocol 只有一个必须要实现的方法 makeIterator()

protocol Sequence{
    associatedtype Iterator: IteratorProtocol
    func makeIterator() -> Iterator
}

makeIterator() 需要返回一个 Iterator,它是一个 IteratorProtocol 类型。

Iterator

Iterator 在 Swift 3.1 标准库中即为 IteratorProtocol,它用来为 Sequence 提供迭代能力。对于 Sequence,我们可以用 for-in 来迭代其中的元素,其实 for-in 的背后是 IteratorProtocol 在起作用。

IteratorProtocol 的定义如下:

public protocol IteratorProtocol{
    associatedtype Element
    public mutating func next() -> Self.Element?
}

其中仅声明了一个 next() 方法,用来返回 Sequence 中的下一个元素,或者当没有下一个元素时返回 nil

associatedtype 声明了元素的类型。

例如:

let animals = ["Antelope", "Butterfly", "Camel", "Dolphin"]
for animal in animals {
    print(animal)
}
// 打印结果:
Antelope
Butterfly
Camel
Dolphin

编译器会把以上代码转换成以下代码:

var animalIterator = animals.makeInterator()
while let animal = animalIterator.next() {
    print(animal)
}

Iterator 是一个单向的结构,它只能向前迭代,而不能后退或者重置。

最简单的 Iterator 实现如下:

struct SimplestIterator:IteratorProtocol{
    typealias Element = Int
    mutating func next() -> Int? {
        return nil
    }
}

next() 的实现返回一个 nil ,这个 Iterator 不会迭代出任何元素。

struct SimplestIntIterator:IteratorProtocol{
    typealias Element = Int
    mutating func next() -> Int? {
        return 1
    }
}

上面这个例子则是实现了一个只返回 1 的 Iterator。

struct SimplestIntIterator:IteratorProtocol{
    typealias Element = Int
    mutating func next() -> Int? {
        return 1
    }
}

在实现 Iterator 时可以省略 Element 的类型声明,Swift 会通过 next() 的返回值类型来自动推导出 Element 的类型。不过对于实现比较复杂的 Iterator,往往还是会加上类型声明这一句,提高代码可读性。

实现一个 Sequence

我们准备实现一个 Iterator,它接收一个字符串数组,并迭代这个数组中所有字符串的首字母。

当数组中的最后一个字符串迭代完毕后,退出迭代。

struct FirstLetterIterator: IteratorProtocol {
    let strings: [String]
    var offset: Int
	
    init(strings: [String]) {
        self.strings = strings
        offset = 0
    }
	
    mutating func next() -> String? {
        guard offset < strings.endIndex else { return nil }
        let string = strings[offset]
        offset += 1
        return string.substring(to: string.index(string.startIndex, offsetBy: 1))
    }
}

这里 Element 类型的声明就省去了,编译器可以根据 next() 的返回值类型推断出 Element 的类型。

有了已经实现好的 Iterator,就可以很简单的用它实现 Sequence。

struct FirstLetterSequence:Sequence{
    let strings: [String]
	
    func makeIterator() -> FirstLetterIterator {
        return FirstLetterIterator(strings: strings)
    }
}

现在我们可以创建一个 FirstLetterSequence,并用 for-in 循环对其迭代:

forletterin FirstLetterSequence(strings: ["apple","banana","orange"]){
    print(letter)
}
/* 打印结果:
a
b
o
*/

以上所述就是小编给大家介绍的《Swift 中的 Sequence 基础篇》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Algorithmic Beauty of Plants

The Algorithmic Beauty of Plants

Przemyslaw Prusinkiewicz、Aristid Lindenmayer / Springer / 1996-4-18 / USD 99.00

Now available in an affordable softcover edition, this classic in Springer's acclaimed Virtual Laboratory series is the first comprehensive account of the computer simulation of plant development. 150......一起来看看 《The Algorithmic Beauty of Plants》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具