2014-06-10 17 views
10

我正在嘗試從書籍slightly tweaked to be generic中爲Matrix示例編寫一個擴展。
我正在嘗試編寫一個名爲getRow的方法,該方法返回給定行處的值序列。如何在Swift中返回一個序列?

在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>see also this)。定義返回通用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循環消耗?

更多關於這個問題:Associated Type Considered Weird

回答

9

喬格勒夫suggested包住結果SequenceOf<T>

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

事實上,這個工作,但我們不得不換map結果成一個輔助類不同於我在C#中的做法。

我不得不承認我還不明白爲什麼SequenceGenerator使用typealias而不是通用的協議(如IEnumerable<T>在C#)。有這種區別的有趣正在進行的討論,所以我會離開好奇的心態幾個環節:

  1. Associated Types Considered Weird
  2. Associated types vs. type parameters - reason for the former?
  3. Abstract Type Members versus Generic Type Parameters in Scala
  4. Generics and protocols
+0

感謝所有這些鏈接 - 非常感謝。 – ColinE

+0

不要忘記SequenceOf已從最新版本的Swift中刪除。 –

1

我認爲你正在被斯威夫特編譯器(這是目前有點片狀)誤導。您的範圍0..self.columns的類型是Range<Int>,這不是SequenceCollection,所以我不認爲它可以通過map使用。

實施工作對我來說:

extension Matrix { 
    func getRow(index: Int) -> T[] { 
    var row = T[]() 
    for col in 0..self.columns { 
     row.append(self[index, col]) 
    } 
    return row 
    } 
} 
+0

我會文件雷達......我該如何保持序列懶惰? –

+0

@丹他們懶惰?如果我在數組上執行映射但不對結果執行任何操作,那麼對所有數組值仍然執行閉包。 – ColinE

+0

奇怪!我認爲,如果它不返回數組,那麼它必須是懶惰的。我會檢查的。 –

相關問題