Swift数字generics?

我有这个function,将从2个数字计算斜边

func hypotenusa(nr1: T, nr2: T) -> T { return sqrt( pow(nr1, 2) + pow(nr2, 2) ) } // v Simpler situation v func addition(nr1: T, nr2: T) -> T { return nr1 + nr2 } 

我想使用generics,所以我不必分别使用Int,Float,Double制作3份副本

但这不起作用,我认为仿制药真的很难配合,请帮帮我:)

Swiftgenerics不像C ++模板。

在C ++中,您可以尝试使用参数化类型,但是在编译器尝试使用某些类型不支持模板尝试执行的模板实例化模板之前,这不是错误。

在Swift中,generics构造只能在首次解析generics构造时以已知的有效方式使用参数化类型。 您可以通过使用协议约束参数化类型来指定这些“已知有效的方法”。

您不能使用generics类型参数调用sqrtpow ,因为这些函数本身不是通用的。 他们有两个定义:

 func pow(_: Double, _: Double) -> Double func pow(lhs: Float, rhs: Float) -> Float func sqrt(x: Double) -> Double func sqrt(x: Float) -> Float 

您可以编写类型特定的hypotenusa版本:

 func hypotenusa(a: Float, b: Float) -> Float func hypotenusa(a: Double, b: Double) -> Double func hypotenusa(a: CGFloat, b: CGFloat) -> CGFloat 

我不确定你为什么要创建一个Int版本,因为很少有直角三角形有整数斜边。

无论如何,您根本不需要定义FloatDouble版本,因为标准库已经提供了在FloatDouble上定义的hypot函数:

 func hypot(_: Double, _: Double) -> Double func hypot(lhs: Float, rhs: Float) -> Float 

您可以为CGFloat创建另一个覆盖:

 func hypot(l: CGFloat, r: CGFloat) -> CGFloat { return hypot(Double(l), Double(r)) } 

至于你的addition函数,它与你的hypotenusa函数有同样的问题: +运算符没有完全定义。 它有一些通用的定义(与sqrtpow不同),但那些只涵盖整数类型(参见IntegerArithmeticType )。 对于浮点类型,没有+的通用定义。 Swift使用显式类型定义所有这些版本的+

 func +(lhs: Float, rhs: Float) -> Float func +(lhs: Int, rhs: UnsafePointer) -> UnsafePointer func +(lhs: UnsafePointer, rhs: Int) -> UnsafePointer func +(lhs: Int, rhs: Int) -> Int func +(lhs: UInt, rhs: UInt) -> UInt func +(lhs: Int64, rhs: Int64) -> Int64 func +(lhs: UInt64, rhs: UInt64) -> UInt64 func +(lhs: Int, rhs: UnsafeMutablePointer) -> UnsafeMutablePointer func +(lhs: UnsafeMutablePointer, rhs: Int) -> UnsafeMutablePointer func +(lhs: Int32, rhs: Int32) -> Int32 func +(lhs: UInt32, rhs: UInt32) -> UInt32 func +(lhs: Int16, rhs: Int16) -> Int16 func +(lhs: UInt16, rhs: UInt16) -> UInt16 func +(lhs: Int8, rhs: Int8) -> Int8 func +(lhs: UInt8, rhs: UInt8) -> UInt8 func +(lhs: Double, rhs: Double) -> Double func +(lhs: String, rhs: String) -> String func +(lhs: Float80, rhs: Float80) -> Float80 

我想这就是你需要的:

您需要显式创建新协议并扩展所需的类型(Int,Float,Double)以符合协议。 你在通用声明中做func addition(nr1: T, nr2: T) -> T {}

阅读我链接的答案以获得更完整的答案。 这里不需要重复。

Sqrt()和pow()都将其参数指定为double或float。 为了满足使用Int,Float和Double这一function的目标,您还需要制作sqrt()和pow()函数的generics。