Program Tip

Swift에서 where 절을 사용하여 배열 유형 확장

programtip 2020. 10. 31. 10:02
반응형

Swift에서 where 절을 사용하여 배열 유형 확장


Accelerate 프레임 워크를 사용하여 [Float] 및 [Double]을 확장하고 싶지만 각각 다른 구현이 필요합니다.

나는 명백한 것을 시도했다.

extension Array<Float> {
}

이 오류가 발생합니다.

"제한된 확장은 'where'절에 지정된 제약 조건을 사용하여 특수화되지 않은 제네릭 유형 'Array'에서 선언되어야합니다."

이런 식으로 Swift 2에서 제네릭 유형을 확장 할 수 있습니까?

이제 예상대로 코드가 작동합니다. 다음은 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
    }
}

특정 유형의 배열 만 확장하려는 경우. _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

함께 작동 Double하고 Float당신이 프로토콜에 맞는지 또는 다른 유형 ArithmeticTypeFloatLiteralConvertible. 당신은 당신의 배열 변화의 액세스 특정 지수에 필요한 경우 SequenceTypeCollectionType당신이 순서로이 작업을 수행 할 수있다.


그래서 질문을 제대로 읽지 못했습니다. FloatingPointTypeDouble, Float 및 CGFloat로 구현 된 기존 프로토콜이므로

예. 요소가 있어야하는 SequenceType에 함수를 추가하기 위해 어제 만했습니다 Equatable. 이것은 요소를 다음으로 제한하는 수정입니다.Float

where 절을 사용해야합니다. 이것은 아래 내 기능입니다.

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은 어쨌든 더 일반적입니다.


Xcode 8.2의 Swift 3

Just need to extend Sequence protocol and provide a where statement.

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)

If you only want to extend a specific Array you have to use a protocol for each type:

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
}

참고URL : https://stackoverflow.com/questions/31806324/extend-array-types-using-where-clause-in-swift

반응형