Swift 序列的局限性在于它们不支持带有抛出 `next()` 方法的迭代器。
存在一些需要这种序列的使用场景,例如 FileHandle 和其他数据流在每次读取操作时都可能产生错误。FailableSequence 模块旨在为这些用例提供支持。
Swift 未来可能会内置对可失败序列的支持。请参阅 swift 语言论坛上的讨论。
Sequence 和 Iterator Swift 标准库的一部分已经为 FailableSequence 和 FailableIterator 进行了复制。
一些 Swift 标准库调用(如 map()
和 filter()
)返回一个 *Array*,而另一些调用(如 drop()
和 prefix()
)返回一种新的 Sequence 类型。只有当序列很大(或无限…映射一个无限序列效果不佳)时,这种差异才会被注意到。作为 Array 返回调用的替代方案,标准库具有 Sequence.lazy
,它提供了对 Sequence 返回调用的访问。
在适当的情况下,FailableSequence 调用与标准库 Sequence.lazy
调用而不是 Sequence
调用匹配。 这样做是为了在检索元素时而不是在构建序列时抛出错误。
有些调用在 Sequence 上可用,但在 FailableSequence 上不可用。 这是因为调用很多,并且实现需要时间。 欢迎提交您需要的调用的任务或拉取请求。
编辑 Package.swift 文件。 将 FailableSequence 添加为依赖项
let package = Package(
name: " ... ",
products: [ ... ],
dependencies: [
.package(url: "https://github.com/berikv/FailableSequence.git", from: "0.0.2") // here
],
targets: [
.target(
name: " ... ",
dependencies: [
"FailableSequence" // and here
]),
]
)
使用 first
和 next()
创建一个可失败序列。
let sequence = failableSequence(first: 0) { number in
let next = number + 1
if next == 3 { throw NumberIsThreeError() }
return next
}
var numbers = [Int]()
var theError: Error?
do {
try sequence.forEach { numbers.append($0) }
} catch {
theError = error
}
// numbers == [0, 1]
// error is NumberIsThreeError
从另一个序列创建一个惰性的可失败 map。
let sequence = (0..<4).failableMap { number -> Int in
let next = number + 1
if next == 3 { throw NumberIsThreeError() }
return next
}
var numbers = [Int]()
var theError: Error?
do {
try sequence.forEach { numbers.append($0) }
} catch {
theError = error
}
// numbers == [1, 2]
// error is NumberIsThreeError
从 FailableSequence 创建一个数组。
// Note, if this sequence would cause the *Array init* to throw an error if number == 3.
let sequence = failableSequence(first: 0) { number in
let next = number + 1
if next == 3 { throw NumberIsThreeError() }
return next
}
let array = try Array(sequence.prefix(2))
// array == [0, 1]
请注意,抛出错误不会结束序列。
let sequence = (0...4).failableMap { number -> Int in
let next = number + 1
if next == 3 { throw NumberIsThreeError() }
return next
}
let array = Array(sequence.skipOnThrowSequence)
// array == [1, 2, 4, 5]
确保您的代码经过充分测试。 运行 ./coverage.sh
以获得概览。
在 MIT 许可下获得许可。 请参阅 license.md