使用 `pow` 的 Swift 2 协议(protocol)扩展

标签 swift protocols

我试图赋予任何数字任意幂的能力(具体来说,2)。这似乎是使用协议(protocol)扩展的绝佳机会,而不是向 FloatDoubleInt 等添加扩展。

protocol Raisable {
    func raise(exponent : Self) -> Self
}

extension Raisable where Self : SignedNumberType {
    func raise(exponent : Double) -> Self {
        return Self(pow(Double(self), exponent))
    }
}

protocol Squarable : Raisable {
    func squared() -> Self
}

extension Squarable {
    func squared() -> Self {
        return self.raise(2)
    }
}

编译器显示“无法找到接受类型为“(Self)”的参数列表的类型“Double”的初始值设定项”。

有什么想法可以改变 raise: 来解决这个问题吗?

提前致谢。

最佳答案

这里有很多重叠的问题,可能无法很好地解决(即使解决了,结果也不会很好)。让我们来看看其中的一些。

protocol Raisable {
    func raise(exponent : Self) -> Self
}

好的,我们已经遇到了第一个问题。考虑如果 SelfIntInt(2).raise(-1)的结果是什么?它应该是 0.5,但这不是一个整数。您打算四舍五入到 1 吗?这绝对与您为 Double 编写的代码不同.

extension Raisable where Self : SignedNumberType {
    func raise(exponent : Double) -> Self {
        return Self(pow(Double(self), exponent))
    }
}

这要求每一个可能的SignedNumberType可与 Double 相互转换,这不是 promise 的,甚至不是可取的。例如,一个复数满足SignedNumberType的所有要求。 ,将复数提升为实数指数是合理的,但是 pow不是正确的功能。您确实需要使用差异化代码来处理这些情况。特别考虑 i^2 的情况,这是真实的,所以只是投影 i到它的实数分量( 0 )上,然后进行平方,这将导致非常令人惊讶的结果。

extension Squarable {
    func squared() -> Self {
        return self.raise(2)
    }
}

除了其他问题之外,这是非常非常慢的(比 self*selfself<<1 在适用的情况下慢几个数量级)。如果它显着提高了可读性,那并不是世界末日,但事实似乎并非如此。

一般来说,Swift 不鼓励采用“某个数字,我不在乎什么类型”的函数。大多数情况下,您需要编写代码来处理数字转换并考虑溢出、截断等情况。如果您想将所有内容提升为 Double ,您通常需要有意这样做,而不是通过协议(protocol)。

但是关于扩展,这里仍然有一些东西需要学习。我们当然可以创建一个squared()轻松方法并将其附加到各种类型。例如:

protocol Multipliable {
    func *(lhs: Self, rhs: Self) -> Self
}

extension Multipliable {
    func squared() -> Self {
        return self * self
    }
}

extension Int: Multipliable {}
extension Double: Multipliable {}

2.squared()
(2.1).squared()

关于使用 `pow` 的 Swift 2 协议(protocol)扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31702831/

相关文章:

ios - 操作扩展 - 多个 NSURLSession

ios - 如何在 Swift 中的自定义数组中按 NSDate 排序

ios - Firebase - 闭包内的用户和 currentUser nil

swift - EXC_BAD_ACCESS 使用协议(protocol)组合

swift - 数组中具有关联类型的协议(protocol) - 替代解决方案

ios - 滚动后表格 View 单元格困惑

ios - UITextView() 不能定义为 nil?

我们可以在 BG96 LwM2M 实现中添加自定义对象吗?

java - com.google 无法解析为类型

ios - 协议(protocol) var {get}