在Swift中使用where子句扩展数组types

我想使用Accelerate框架来扩展[Float]和[Double],但是每个都需要不同的实现。

我试过很明显的:

extension Array<Float> { } 

并得到这个错误:

“约束扩展必须在非专用genericstypes'Array'上声明,其约束由'where'子句指定”

以这种方式扩展Swift 2中的genericstypes是否可行?

我已经得到了代码正常工作。 以下是一个使用Accelerate框架显示总和的示例。

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

如果你想扩展只有特定types的数组。 你应该扩展_ArrayType协议。

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

如果你扩展Array你只能确保你的元素符合其他协议。 即:

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

更新:使用Swift 3.1 https://github.com/apple/swift/blob/master/CHANGELOG.md

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

斯威夫特3救援!

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

怎么样

 extension CollectionType where Generator.Element == Double { } 

或者如果你想多一点:

 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 

使用DoubleFloat或符合协议ArithmeticTypeFloatLiteralConvertible任何其他types。 如果您需要访问数组的特定索引,请将SequenceType更改为CollectionType因为您无法使用序列执行此操作。

所以我没有正确地阅读这个问题。 FloatingPointType是由Double,Float和CGFloat实现的现有协议

是。 我只是在昨天才添加一个函数给SequenceType,其中的元素必须是Equatable 。 这是一个将元素限制为Float的修改

你需要使用一个where子句。 这是我的function如下。

 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我不能使这个工作的数组,但SequenceType是更一般的反正。

如果你只想扩展一个特定的Array你必须为每个types使用一个协议:

 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在Xcode 8.2上

只需要扩展序列协议,并提供一个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)