used type only has generic functions extension constraint because associated swift generics swift2 swift-extensions

type - public extension swift



Extienda los tipos de matriz usando la cláusula where en Swift (6)

Entonces no leí la pregunta correctamente. FloatingPointType es un protocolo existente implementado por Double, Float y CGFloat, por lo que

Si. Solo lo hice ayer para agregar una función a SequenceType donde los elementos tenían que ser Equatable . Esta es una modificación para restringir los elementos a Float

Necesita usar una cláusula where. Esta es mi función a continuación.

public extension SequenceType where Self.Generator.Element: FloatingPointType { public func splitAt(separator: Generator.Element) -> [[Generator.Element]] { var ret: [[Generator.Element]] = [] var thisPart: [Generator.Element] = [] for element in self { if element == separator { ret.append(thisPart) thisPart = [] } else { thisPart.append(element) } } ret.append(thisPart) return ret } } [Float(1), Float(2), Float(3), Float(4)].splitAt(Float(2)) // returns [[1],[3, 4]] [Double(1), Double(2), Double(3), Double(4)].splitAt(Double(3)) // returns [[1, 2],[4]]

NB: No podría hacer que esto funcione para una matriz, pero SequenceType es más general de todos modos.

Me gustaría usar el marco Acelerar para extender [Float] y [Double] pero cada uno de estos requiere una implementación diferente.

Intenté lo obvio:

extension Array<Float> { }

y obtén este error:

"La extensión restringida debe declararse en el tipo genérico no especializado ''Array'' con restricciones especificadas por una cláusula ''where''"

¿Es posible extender tipos genéricos en Swift 2 de esta manera?

Tengo el código funcionando como se esperaba ahora. Aquí hay un ejemplo que muestra una suma usando el marco Acelerar.

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 } }


Qué tal si

extension CollectionType where Generator.Element == Double { }

O si quieres un poco más:

protocol ArithmeticType { func +(lhs: Self, rhs: Self) -> Self func -(lhs: Self, rhs: Self) -> Self func *(lhs: Self, rhs: Self) -> Self func /(lhs: Self, rhs: Self) -> Self } extension Double : ArithmeticType {} extension Float : ArithmeticType {} extension SequenceType where Generator.Element : protocol<FloatLiteralConvertible, ArithmeticType> { var sum : Generator.Element { return reduce(0.0, combine: +) } var product : Generator.Element { return reduce(1.0, combine: *) } } stride(from: 1.0, through: 10.0, by: 1.0).sum // 55 [1.5, 2.0, 3.5, 4.0, 5.5].product // 231

Funciona con Double and Float o cualquier otro tipo que se ajuste a los protocolos ArithmeticType y FloatLiteralConvertible . Si necesita acceder a índices específicos de su matriz, cambie SequenceType a CollectionType ya que no puede hacerlo con una secuencia.


Si desea extender solo una matriz con un tipo específico. Debe extender el protocolo _ArrayType.

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

Si extiende Array , solo puede asegurarse de que su elemento esté conformado por algún otro protocolo. es decir:

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

Actualizado: con Swift 3.1 https://github.com/apple/swift/blob/master/CHANGELOG.md

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


Si solo desea extender una Array específica, debe usar un protocolo para cada tipo:

protocol DoubleValue { var value: Double { get } } extension Double: DoubleValue { var value: Double { return self } } extension Array where Element: DoubleValue { // use the value property } // the same for Float protocol FloatValue { var value: Float { get } } extension Float: FloatValue { var value: Float { return self } } extension Array where Element: FloatValue { // use the value property }


Swift 3 al rescate !!

extension Collection where Iterator.Element == Int { // `Collection` can be `Sequence`, etc }


Swift 3 en Xcode 8.2

Solo necesita extender el protocolo de secuencia y proporcionar una declaración where.

let someString = "1, 2, 3, 4, 5, 6, 7, 8" extension String { func toArrayOfElements() -> [String] { return self.components(separatedBy: ", ") } } extension Sequence where Iterator.Element == String { func toInt() -> [Int] { return self.map { Int($0)! } } } let arrayOfStrings = someString.toArrayOfElements() print(arrayOfStrings) let arrayOfInts = arrayOfStrings.toInt() print(arrayOfInts)