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

Swift 3.0中浮点元素数组的扩展,swift,floating-point,swift3,swift-extensions,Swift,Floating Point,Swift3,Swift Extensions,如何在Swift 3.0中简洁地编写数组的扩展,该扩展既适用于浮点类型,也适用于双元素类型 以下操作不起作用: extension Array where Element: FloatingPoint { public func multiply(mult: Double) -> [Double] { return self.map{Double($0) * mult} } } 错误是 无法在当前上下文中推断闭包类型 为什么不能推断闭包类型?这是编译器当前

如何在Swift 3.0中简洁地编写
数组
的扩展,该扩展既适用于
浮点
类型,也适用于
双元素
类型

以下操作不起作用:

extension Array where Element: FloatingPoint
{
    public func multiply(mult: Double) -> [Double] {
        return self.map{Double($0) * mult}
    }
}
错误是

无法在当前上下文中推断闭包类型

为什么不能推断闭包类型?这是编译器当前的一个限制,还是无法推断闭包类型的原因

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

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

对成员“*”的引用不明确


我也不确定这个错误的原因。

从逻辑上讲,您的扩展应该通过将同质浮点类型的数组与相同类型的值相乘,然后返回该类型的数组来工作。您可以简单地用类型为
Element
的参数和返回值
[Element]
来表示这一点:

// this could also just be an extension of Sequence
extension Array where Element : FloatingPoint {

    public func multiply(by factor: Element) -> [Element] {
        return self.map { $0 * factor }
    }
}
因此,对于
[Float]
,这将接受类型为
Float
的参数,并返回
[Float]

但是,如果我真的想返回一个Double的数组怎么办

我认为不可能从任意的
浮点
(甚至
二进制浮点
)符合实例构建
,因为这两个协议都不符合(尽管它们确实需要实现IEEE 754规范的各个方面)实际上定义了一致类型的精确编码

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

extension Sequence where Iterator.Element == Float {

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

extension Sequence where Iterator.Element == Double {

    public func multiply(by factor: Double) -> [Double] {
        return self.map { $0 * factor }
    }
}
或者,如果您计划使用范围更广的类型,您可以使用
协议
,以定义允许一致性类型将其值表示为
双值的要求:

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 { $0._asDouble() * factor }
    }
}

@哈米什按照你的建议去做,谢谢!这也许足够好了。但是,如果我真的想返回一个Double的数组怎么办?(例如,考虑一个情况,而不是控制<代码> Mult < /Case>参数,就像上面的例子中那样,我没有参数,而是乘一个我没有写的函数,它返回<代码>双< /代码>。
Double
和一个
[Double]
应该被返回。我继续并将我的评论转换为一个答案:)@Hamish您可能对使用初始值设定项的DoubleConvertible实现感兴趣,正如Martin R建议的,我在这里使用的@LeoDabus是的,这是解决“一种可以传递给函数给定重载的类型”(在本例中,
Double
init(:)
)。实际上,为了处理不同类型之间的转换,您也可以对其进行泛化,例如,请参见。@LeoDabus Swift 2也有协议组合;)它只是有不同的语法(
协议
).我建议将其作为一个答案:)Swift是否已经有了
ConvertibleToDouble
协议或类似协议?@Danra我不知道(请随意证明我错了:)