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)