我试图为书中的Matrix
示例slightly tweaked to be generic写一个扩展名。
我正在尝试编写一个名为getRow
的方法,该方法返回给定行的值序列。
在C#中,我会写这个:
IEnumerable<T> GetRow (int row)
{
return Enumerable
.Range (0, this.columns)
.Select ((column) => this.grid[row, columns]);
}
或者
IEnumerable<T> GetRow (int row)
{
for (var column = 0; column < this.columns; column++) {
yield return this.grid[row, column];
}
}
我不知道怎么在Swift中这样做。
Sequence
似乎等同于IEnumerable<T>
,但我不明白为什么它使用typealias
而不是仅定义为Sequence<T>
({{3} }})。定义返回泛型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] })
}
}
然后我摆脱了<T>
(但它应该是通用的?):
extension Matrix {
func getRow(index: Int) -> Sequence {
return map(0..self.columns, { self[index, $0] })
}
}
这个编译!但是我无法使用它:
var row = grid.getRow(0)
// 'Sequence' does not conform to protocol '_Sequence_'
for i in row {
println("\(i)")
}
如何正确输入map
结果,以便在for..in
循环中使用?
有关此问题的更多信息:see also this
答案 0 :(得分:10)
Joe Groff suggested将结果包装在SequenceOf<T>
:
extension Matrix {
func getRow(index: Int) -> SequenceOf<T> {
return SequenceOf(map(0..self.columns, { self[index, $0] }))
}
}
确实,这有效,但是我们必须将map
结果包装成一个辅助类,这与我在C#中的方式不同。
我必须承认,我还不明白为什么Sequence
和Generator
使用typealias
并且不是通用协议(例如C#中的IEnumerable<T>
)。关于这种区别有一个有趣的持续讨论,所以我会留下一些好奇心的链接:
答案 1 :(得分:1)
我认为你被Swift编译器误导了(目前有点不稳定)。您的范围0..self.columns
的类型为Range<Int>
,不是Sequence
或Collection
,因此我认为不能通过{{1}使用它}。
实施对我有用:
map