我正在尝试从“Matrix”一书中为稍微调整为通用的示例编写一个扩展。
我正在尝试编写一个名为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];
}
}不过,我不知道怎么用斯威夫特来做这个。
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] })
}
}然后我去掉了<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循环中使用它?
有关此问题的更多信息:关联类型被认为是奇怪的
发布于 2014-06-13 23:38:19
Joe 建议在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> )。关于这一区别,正在进行一场有趣的讨论,因此我将为好奇的头脑留几个链接:
发布于 2014-06-10 09:36:59
我认为你被Swift编译器误导了(目前这有点古怪)。range 0..self.columns的类型是Range<Int>,它不是Sequence或Collection,所以我不认为它可以通过map使用。
执行工作对我来说是可行的:
extension Matrix {
func getRow(index: Int) -> T[] {
var row = T[]()
for col in 0..self.columns {
row.append(self[index, col])
}
return row
}
}https://stackoverflow.com/questions/24137062
复制相似问题