我可以将相同的扩展名应用于许多类而无需复制粘贴吗?

时间:2014-07-26 02:58:00

标签: swift double cgfloat

假设我有CGFloat的这个扩展名

extension CGFloat {
    // common 
    public var thrice: CGFloat { return self * 3.0 }
    public var twice: CGFloat { return self * 2.0 }
    public var half: CGFloat { return self * 0.5 }
    public var third: CGFloat { return self / 3.0 }
    public var fourth: CGFloat { return self * 0.25 }
    public var sixth: CGFloat { return self / 6.0 }
    public var eighth: CGFloat { return self * 0.125 }
    public var twelfth: CGFloat { return self / 12.0 }
    public var sixteenth: CGFloat { return self * 0.0625 }

    //
    public var inverse: CGFloat { return 1.0 / self }
}

我想要做的是将这些应用于CGFloat,Double和Float,而无需复制/粘贴代码。这是可能吗?

谢谢!

1 个答案:

答案 0 :(得分:9)

你不能通过扩展类型(一次性全部)来实现,但你可以使用模板化函数来实现:

protocol FloatLiteralMultipliable: FloatLiteralConvertible {
    func *(lhs: Self, rhs: Self) -> Self
    func /(lhs: Self, rhs: Self) -> Self
}

extension Float: FloatLiteralMultipliable {}
extension CGFloat: FloatLiteralMultipliable {}
extension Double: FloatLiteralMultipliable {}

func thrice<T: FloatLiteralMultipliable>(value: T) -> T { return value * 3.0 }
func twice<T: FloatLiteralMultipliable>(value: T) -> T { return value * 2.0 }
func half<T: FloatLiteralMultipliable>(value: T) -> T { return value / 2.0 }
func third<T: FloatLiteralMultipliable>(value: T) -> T { return value / 3.0 }
func fourth<T: FloatLiteralMultipliable>(value: T) -> T { return value / 4.0 }
func sixth<T: FloatLiteralMultipliable>(value: T) -> T { return value / 6.0 }
func eighth<T: FloatLiteralMultipliable>(value: T) -> T { return value * 0.125 }
func twelfth<T: FloatLiteralMultipliable>(value: T) -> T { return value / 12.0 }
func sixteenth<T: FloatLiteralMultipliable>(value: T) -> T { return value / 0.0625 }

func inverse<T: FloatLiteralMultipliable>(value: T) -> T { return 1.0 / value }

thrice(Float(10.0)) // 30.0
half(CGFloat(2)) // 1.0
inverse(Double(1.0/10.0)) // 10.0

注意:我只是在我的示例调用中显式构造类型,以证明函数可以与每种类型一起使用