swift - 快速惰性序列 - 为什么在引入定义时编译器会抱怨
问题描述
我正在使用 Ints 的惰性序列:
let a = [1,2,3].lazy
我首先定义一个 Ints 流,如下所示:
protocol Stream: LazySequenceProtocol where Element == Int {}
extension LazySequence: Stream where Element == Int {}
extension LazyMapSequence: Stream where Element == Int {}
我将用流做复杂的事情,但为了演示这个问题,我会保持简单。我扩展了流以允许递增值:
extension Stream {
func increment() -> some Stream {
map{ value in
return value + 1
}
}
}
print(Array(a.increment())) // Prints [2, 3, 4]
请注意, a.increment() 是一个惰性函数,因此需要被 Array() 包围才能将结果转换为数组以进行打印。
还要注意使用 Swift 5.1 中引入的单词“some”来表示不透明类型,并允许我们以这种方式实现流 - 如果没有不透明类型,这并不是那么简单。
而且我可以做更多有趣的事情,比如在自身后面插入 10 倍的值:
extension Stream {
func insert10x() -> some Stream {
flatMap{ value in
return [value, value*10]
}
}
}
print(Array(a.insert10x())) // Prints [1, 10, 2, 20, 3, 30]
这意味着我可以开始以不同的方式组合我的函数:
print(Array(a.insert10x().increment())) // Prints [2, 11, 3, 21, 4, 31]
print(Array(a.increment().insert10x())) // Prints [2, 20, 3, 30, 4, 40]
以上所有内容都按预期编译和工作。
但是......如果我引入一个额外的行,例如下面的“let multiplier = 10”,那么我会得到编译器错误:
extension Stream {
func insert10xVersion2() -> some Stream {
flatMap{ value in // Error 1
let multiplier = 10
return [value, value * multiplier] // Error 2
}
}
}
print(Array(a.insert10xVersion2())) // Should prints [1, 10, 2, 20, 3, 30]
两个编译器错误:
错误 1: 不推荐使用“flatMap”:对于闭包返回可选值的情况,请使用 compactMap(_:)。使用 'compactMap(_:) 代替。
错误 2: 无法将类型“[Int]”的返回表达式转换为返回类型“Int?”
这两个错误似乎都表明编译器已决定 flatMap 正在处理可选项,因此鼓励使用 compactMap 代替。
但我会认为这应该产生与第一个版本相同的结果!
也许这是一个编译器错误,但我想我先在这里检查一下是否有人能看到我的代码有问题?
解决方案
推荐阅读
- node.js - 使用猫鼬查找 phoneNumber 正则表达式
- macos - Apple M1 到 Linux x86_64:无法识别的命令行选项“-m64”
- android - 如何获取 Kotlin 类而不是 java 类
- reactjs - 错误:“突变”类型上的未知字段“讨论”。使用 Relay 和 React `useMutation` 钩子
- python - 如何将列的重复值转置到新列的特定位置?
- docker - 如何从 docker 镜像启动 AWX
- javascript - 如何在 React 三纤维中创建第一人称控制?
- flutter - 使用 WebRTC 的 Flutter 视频聊天总是获得 RTCPeerConnectionStateFailed 状态
- amazon-web-services - 使用 MariaDB JDBC 客户端通过 AWS RDS 代理执行 IAM 身份验证
- ruby-on-rails - Travis CI 上没有用于系统测试的输出