Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extend array types using where clause in Swift

I'd like to use the Accelerate framework to extend [Float] and [Double] but each of these requires a different implementation.

I tried the obvious:

extension Array<Float> { } 

and get this error:

"Constrained extension must be declared on the unspecialised generic type 'Array' with constraints specified by a 'where' clause"

Is it posible to extend generic types in Swift 2 in this way?

I've got the code working as expected now. Here's an example showing a summation using the Accelerate framework.

extension _ArrayType where Generator.Element == Float {      func quickSum() -> Float {         var result: Float = 0         if var x = self as? [Float] {             vDSP_sve(&x, 1, &result, vDSP_Length(x.count))         }         return result     } }  extension _ArrayType where Generator.Element == Double {      func quickSum() -> Double {         var result: Double = 0         if var x = self as? [Double] {             vDSP_sveD(&x, 1, &result, vDSP_Length(x.count))         }         return result     } } 
like image 855
GScrivs Avatar asked Aug 04 '15 10:08

GScrivs


People also ask

Can we extend protocol in Swift?

In Swift, you can even extend a protocol to provide implementations of its requirements or add additional functionality that conforming types can take advantage of. For more details, see Protocol Extensions. Extensions can add new functionality to a type, but they can't override existing functionality.

Can extensions have stored properties in Swift?

As you may know Swift does not allow stored properties into extensions. That's by design: “Extensions may not contain stored properties.”

Why use extensions in Swift?

Extensions, well, extend existing Swift named types — i.e., structs, classes, enums, and protocol — so you can add more functionality to them. This enables you to insert your own code into existing system code to which you wouldn't otherwise have access, such as the Foundation framework.


2 Answers

If you want to extend only array with specific type. You should extend _ArrayType protocol.

extension _ArrayType where Generator.Element == Int {     func doSomething() {        ...     } } 

If you extend Array you can only make sure your element is conformed some protocol else. i.e:

extension Array where Element: Equatable {     func doSomething() {        ...     } } 

Updated: With Swift 3.1 https://github.com/apple/swift/blob/master/CHANGELOG.md

extension Array where Element == Int {     func doSomething() {        ...     } } 
like image 174
Huy Le Avatar answered Oct 19 '22 22:10

Huy Le


Swift 3 to the rescue!!

extension Collection where Iterator.Element == Int {     // `Collection` can be `Sequence`, etc } 
like image 23
Ben Lu Avatar answered Oct 19 '22 23:10

Ben Lu