如何在Swift中返回序列?

Dan*_*mov 11 generics generator map for-in-loop swift

我正在尝试Matrix为本书中的示例编写扩展,稍微调整为通用.
我正在尝试编写一个调用方法getRow,该方法返回给定行的值序列.

在C#中,我会写这个:

IEnumerable<T> GetRow (int row)
{
    return Enumerable
        .Range (0, this.columns)
        .Select ((column) => this.grid[row, columns]);
}
Run Code Online (Sandbox Code Playgroud)

或者

IEnumerable<T> GetRow (int row)
{
    for (var column = 0; column < this.columns; column++) {
        yield return this.grid[row, column];
    }
}
Run Code Online (Sandbox Code Playgroud)

我不知道如何在Swift中做到这一点.

Sequence似乎是等价的,IEnumerable<T>但我不明白它为什么使用typealias而不仅仅被定义为Sequence<T>(另见这一点).定义返回泛型的方法Sequence<T>不起作用:

extension Matrix {
    // Cannot specialize non-generic type 'Sequence'
    func getRow<T>(index: Int) -> Sequence<T> {
        return map(0..self.columns, { self[index, $0] })
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我摆脱了<T>(但它应该是通用的?):

extension Matrix {
    func getRow(index: Int) -> Sequence {
        return map(0..self.columns, { self[index, $0] })
    }
}
Run Code Online (Sandbox Code Playgroud)

这编译!但是我不能用它:

var row = grid.getRow(0)
// 'Sequence' does not conform to protocol '_Sequence_'
for i in row {
    println("\(i)")
}
Run Code Online (Sandbox Code Playgroud)

如何正确输入map结果以便for..in循环使用?

关于这个问题的更多信息:相关类型被认为是奇怪的

Dan*_*mov 10

Joe Groff 建议将结果包装成SequenceOf<T>:

extension Matrix {
    func getRow(index: Int) -> SequenceOf<T> {
        return SequenceOf(map(0..self.columns, { self[index, $0] }))
    }
}
Run Code Online (Sandbox Code Playgroud)

实际上,这是有效的,但我们必须将map结果包装到一个辅助类中,这与我在C#中的方式不同.

我不得不承认我还不明白为什么SequenceGenerator使用typealias而且不是通用协议(比如IEnumerable<T>在C#中).关于这种区别有一个有趣的持续讨论,所以我将留下一些好奇心的链接:

  1. 相关类型被认为是奇怪的
  2. 关联类型与类型参数 - 前者的原因?
  3. 抽象类型成员与Scala中的泛型类型参数
  4. 泛型和协议