Swift 3.0中浮点元素数组的扩展
如何在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} } } 错误是 无法在当前上下文中推断闭包类型 为什么不能推断闭包类型?这是编译器当前
数组
的扩展,该扩展既适用于浮点
类型,也适用于双元素
类型
以下操作不起作用:
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我不知道(请随意证明我错了:)