2015-02-23 36 views
3

我正在嘗試編寫一個用於基準測試各種SequenceType實現的迭代性能的函數。它應該簡單地總結序列的內容,其中所有元素都是Int s。我與表達上的功能通用約束掙扎......如何爲SequenceType實現泛型函數,其中Generator.Element是Int類型

func sum<S: SequenceType where S.Generator.Element: Int>(s: S) -> Int { 
    var sum = 0 
    for i in s { 
     sum += i 
    } 
    return sum 
} 

這將導致以下兩個錯誤:

  • 類型‘S.Generator.Element’受限於非協議類型’Int’
  • 二元運算'+=‘不能應用於類型爲’Int'’S.Generator.Element’的操作數

有沒有辦法定義這個函數來處理任何SequenceType實現,其中的元素專用於Int

+0

我試圖力低垂到'詮釋',但這招致輕微的表現懲罰,並扭曲了這個功能的目的離子。 – Palimondo 2015-02-23 14:43:10

+0

我知道我可以使用'reduce'函數,但是我的目的是明確地測試'for in'循環中的序列,它的性能特點與'reduce'略有不同。 – Palimondo 2015-02-23 14:45:13

回答

5

約束應該是S.Generator.Element == Int

func sum<S: SequenceType where S.Generator.Element == Int>(s: S) -> Int { 
    var sum = 0 
    for i in s { 
     sum += i 
    } 
    return sum 
} 

略有整數類型更普遍的:

func sum<S: SequenceType, T : IntegerType where S.Generator.Element == T >(s: S) -> T { 
    var sum : T = 0 
    for i in s { 
     sum += i 
    } 
    return sum 
} 
+0

我可以發誓我已經嘗試過這種語法......但顯然沒有。謝謝! :-) – Palimondo 2015-02-23 14:57:14

+0

儘管該函數對於預期目的是無用的,但從Swift 1.2開始,因爲編譯器顯然沒有內聯和專門化測量的SequenceType實現,並且比每次總是手動編寫for-in循環要慢幾個數量級測試用例。 'reduce'函數似乎有某種特殊情況優化,與「手動循環」相當。 – Palimondo 2015-02-23 15:09:43

0

一個更新版本的雨燕3.1:

func sum<S: Sequence>(_ s: S) -> Int where S.Iterator.Element == Int { 
    return s.reduce(0){$0 + $1} 
}