Swift 3.0 中浮点元素数组的扩展
Extension of Array of FloatingPoint Elements in Swift 3.0
如何在 Swift 3.0 中紧凑地编写一个 Array
的扩展,它适用于 Float
和 Double
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 }
}
}
如何在 Swift 3.0 中紧凑地编写一个 Array
的扩展,它适用于 Float
和 Double
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]
:
// 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 }
}
}