swift - 将 Range 和 StrideTo 转换为 Sequence 时出现异常错误
问题描述
以下函数会产生编译器错误:
func iterateColumnsAlongGravity<S: Sequence>(using block: (_ indexes: S) -> ())
where S.Element == Int {
switch gravityDirection {
case .bot:
for i in stride(from: 0, to: w * h, by: h) {
// 'Range<Int>' is not convertible to 'S'
block(i..<(i + h))
}
case .top:
for i in stride(from: 0, to: w * h, by: h) {
// 'ReversedCollection<(Range<Int>)>' is not convertible to 'S'
block((i..<(i + h)).reversed())
}
case .left:
for y in 0..<h {
let indexes = stride(from: y, to: w * h, by: h).reversed()
// '([Int]) -> ()' is not convertible to '(S) -> ()'
block(indexes)
}
case .right:
for y in 0..<h {
// '(StrideTo<Int>) -> ()' is not convertible to '(S) -> ()'
let indexes = stride(from: y, to: w * h, by: h)
block(indexes)
}
}
}
我不明白为什么编译器不转换 Range<Int>
为S
(以及其他类型),而Range
is 显然符合Sequence
并且它的元素是Int
.
更奇特的是,如果我用block
类似签名的类方法替换,没有任何错误:
func printIntSequence<S: Sequence>(_ s: S) where S.Element == Int {
for i in s {
print(i)
}
}
func typeConversionTest() {
switch gravityDirection {
case .bot:
for i in stride(from: 0, to: w * h, by: h) {
printIntSequence(i..<(i + h))
}
case .top:
for i in stride(from: 0, to: w * h, by: h) {
printIntSequence((i..<(i + h)).reversed())
}
case .left:
for y in 0..<h {
let indexes = stride(from: y, to: w * h, by: h).reversed()
printIntSequence(indexes)
}
case .right:
for y in 0..<h {
let indexes = stride(from: y, to: w * h, by: h)
printIntSequence(indexes)
}
}
}
iterateColumnsAlongGravity(using:)
和typeConversionTest()
第一个将块作为参数的唯一区别。
解决方案
在Swift 论坛的讨论中,披露了以下信息:
- 我试图实现的被称为更高等级的多态性,这个大特性还没有添加到 Swift 中。
可能最简单的解决方案是丢弃泛型并
StrideTo<Int>
在此处使用。func iterateColumnsAlongGravity(using block: (_ indexes: StrideTo<Int>) -> ()) { switch gravityDirection { case .bot: for i in stride(from: 0, to: w * h, by: h) { block(stride(from: i, to: i + h, by: 1)) } case .top: for i in stride(from: 0, to: w * h, by: h) { block(stride(from: i + h - h, to: i - h, by: -1)) } case .left: for y in 0..<h { block(stride(from: (w - 1) * h + y, to: -1, by: -h)) } case .right: for y in 0..<h { block(stride(from: y, to: w * h, by: h)) } } }
推荐阅读
- python - Python 中的异常处理以实现持续执行
- 3d - 为 .dae 3d 模型添加纹理
- javascript - 调试通过 ngrok 运行的 JavaScript 代码
- swift - Swift Firebase Twitter 登录:无法获取凭据
- c++ - 什么是 .c.obj / .cpp.obj 文件?
- c# - GAC 之外的参考资料
- android - AndroidManifest.xml 不允许匹配“[xX][mM][lL]”的处理指令目标
- python - 如何在 python(pandas) 中获得文件编辑权限
- linux - UNIX/LINUX 递归计数
- c++ - 共享可执行文件时找不到库 gcc dll 错误