74

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

8 に答える 8

15

どうですか

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に準拠するその他のタイプのArithmeticTypeやで動作しFloatLiteralConvertibleます。配列の特定のインデックスにアクセスする必要がある場合は、シーケンスではこれを行うことができないため、に変更SequenceTypeしてください。CollectionType

于 2015-08-04T10:30:02.583 に答える
4

特定のものだけを拡張したい場合はArray、タイプごとにプロトコルを使用する必要があります。

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
}
于 2015-08-04T10:42:13.873 に答える
4

なので、質問をよく読んでいませんでした。 FloatingPointTypeは、Double、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はとにかくより一般的です。

于 2015-08-04T10:36:23.027 に答える
0

これは私が使用したものですSwift 5

extension Array where ArrayLiteralElement == Float {

}
于 2021-07-22T01:18:31.023 に答える