Swift 3.0 中浮点元素数组的扩展

Extension of Array of FloatingPoint Elements in Swift 3.0

如何在 Swift 3.0 中紧凑地编写一个 Array 的扩展,它适用于 FloatDouble Element 类型?

以下无效:

extension Array where Element: FloatingPoint
{
    public func multiply(mult: Double) -> [Double] {
        return self.map{Double([=11=]) * mult}
    }
}

错误是

Unable to infer closure type in the current context

为什么不能推断闭包类型?这是编译器的当前限制,还是无法推断闭包类型的充分理由?

更明确的版本也不起作用:

extension Array where Element: FloatingPoint
{
    public func multiply(mult: Double) -> [Double] {
        return self.map{(x: Element) -> Double in Double(v: x) * mult}
    }
}

这次有错误

Ambiguous reference to member '*'

我又在哪里不确定这个错误的原因。

从逻辑上讲,您的扩展应该通过将同质 floating-point 类型的数组与相同类型的值相乘,然后 returning 该类型的数组来工作。您可以简单地用 Element 类型的参数和 [Element]:

的 return 来表达这一点
// this could also just be an extension of Sequence
extension Array where Element : FloatingPoint {

    public func multiply(by factor: Element) -> [Element] {
        return self.map { [=10=] * factor }
    }
}

因此对于 [Float],这将接受 Float 和 return 类型的参数 [Float].

However, what if I indeed want to return an array of Double?

我不相信可以从任意FloatingPoint(甚至BinaryFloatingPoint)符合实例构造Double,因为这两个协议(尽管它们确实需要实现 IEEE 754 规范的各个方面)实际上都定义了符合类型的精确编码。

但是,如果您真的想要这个,您可以只写两个重载——一个用于 Float 个元素,一个用于 Double 个元素:

extension Sequence where Iterator.Element == Float {

    public func multiply(by factor: Double) -> [Double] {
        return self.map { Double([=11=]) * factor }
    }
}

extension Sequence where Iterator.Element == Double {

    public func multiply(by factor: Double) -> [Double] {
        return self.map { [=11=] * factor }
    }
}

或者,如果您计划使它适用于更广泛的类型,您可以使用 protocol 来定义允许符合类型将其值表达为 Double:

protocol ConvertibleToDouble {
    func _asDouble() -> Double
}

extension Float : ConvertibleToDouble {
    func _asDouble() -> Double { return Double(self) }
}

extension Double : ConvertibleToDouble {
    func _asDouble() -> Double { return self }
}

extension Sequence where Iterator.Element : ConvertibleToDouble {

    func multiply(by factor: Double) -> [Double] {
        return self.map { [=12=]._asDouble() * factor }
    }
}