如何在swift中为浮点值编写泛型函数

时间:2017-04-03 03:01:43

标签: swift generics floating-point protocols

我想在swift中对浮点类型调用浮点方法。

func example<T : FloatingPoint>(_ x:T) -> T {
    return cos(cbrt(x + 1))
}

有没有比这更好的方法?

protocol SupportsFloatingPoint : FloatingPoint {
    var cubeRoot:Self { get }
    var cosine:Self { get }
}

extension Double : SupportsFloatingPoint {
    var cubeRoot:Double { return Darwin.cbrt(self) }
    var cosine:Double { return Darwin.cos(self) }
}

extension Float : SupportsFloatingPoint {
    var cubeRoot:Float { return Darwin.cbrt(self) }
    var cosine:Float { return Darwin.cos(self) }
}

func cbrt<T : SupportsFloatingPoint>(_ x:T) -> T {
    return x.cubeRoot
}

func cos<T : SupportsFloatingPoint>(_ x:T) -> T {
    return x.cosine
}

func example<T : SupportsFloatingPoint>(_ x:T) -> T {
    return cos(cbrt(x - 1))
}

请注意,此处添加运算符。您可以在SupportsFloatingPoint类型上执行-*/但不能+

1 个答案:

答案 0 :(得分:1)

您不需要新协议。您可以扩展现有的FloatingPoint协议以支持类型:

// Just for fun :)
prefix operator √
prefix operator ∛

extension FloatingPoint where Self == Double {
    var squareRoot: Self { return sqrt(self) }
    var cubeRoot: Self { return cbrt(self) }
    var sine: Self { return sin(self) }
    var cosine: Self { return cos(self) }

    static prefix func √(_ x: Self) -> Self { return x.squareRoot }
    static prefix func ∛(_ x: Self) -> Self { return x.cubeRoot }
}

extension FloatingPoint where Self == Float {
    var squareRoot: Self { return sqrt(self) }
    var cubeRoot: Self { return cbrt(self) }
    var sine: Self { return sin(self) }
    var cosine: Self { return cos(self) }

    static prefix func √(_ x: Self) -> Self { return x.squareRoot }
    static prefix func ∛(_ x: Self) -> Self { return x.cubeRoot }
}

print(Double.pi.cosine)
print(√25.0)
print(∛8.0)

不可否认,有很多代码重复,我正在研究如何最小化。从好的方面来说,至少这是所有静态的,可内联的代码,它们可以生成非常快的机器代码。