Следующая функция выдает ошибки компилятора :
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
, очевидно, соответствует 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()
в том, что первый принимает блок в качестве параметра.