我想让函数接受Swift中的任何数字(Int,Float,Double,...)
func myFunction <T : "What to put here"> (number : T) -> {
//...
}
不使用NSNumber
答案 0 :(得分:52)
更新:以下答案原则上仍然适用,但Swift 4完成了数字协议的重新设计,因此添加自己的协议通常是不必要的。在构建自己的系统之前,请先查看standard library's numeric protocols。
这实际上不可能在Swift中开箱即用。要做到这一点,你需要创建一个新协议,使用你将在泛型函数中使用的任何方法和运算符声明。此过程适用于您,但具体细节将取决于您的通用功能的作用。以下是如何为获得数字n
并返回(n - 1)^2
的函数执行此操作。
首先,定义你的协议,使用运算符和一个Int
的初始化器(这样我们可以减去一个)。
protocol NumericType {
func +(lhs: Self, rhs: Self) -> Self
func -(lhs: Self, rhs: Self) -> Self
func *(lhs: Self, rhs: Self) -> Self
func /(lhs: Self, rhs: Self) -> Self
func %(lhs: Self, rhs: Self) -> Self
init(_ v: Int)
}
所有数值类型已经实现了这些,但此时编译器并不知道它们符合新的NumericType
协议。你必须明确这一点 - Apple称之为“通过扩展声明协议采用”。我们将对Double
,Float
以及所有整数类型执行此操作:
extension Double : NumericType { }
extension Float : NumericType { }
extension Int : NumericType { }
extension Int8 : NumericType { }
extension Int16 : NumericType { }
extension Int32 : NumericType { }
extension Int64 : NumericType { }
extension UInt : NumericType { }
extension UInt8 : NumericType { }
extension UInt16 : NumericType { }
extension UInt32 : NumericType { }
extension UInt64 : NumericType { }
现在我们可以使用NumericType
协议作为通用约束来编写我们的实际函数。
func minusOneSquared<T : NumericType> (number : T) -> T {
let minusOne = number - T(1)
return minusOne * minusOne
}
minusOneSquared(5) // 16
minusOneSquared(2.3) // 1.69
minusOneSquared(2 as UInt64) // 1
答案 1 :(得分:0)
作为一个关于评论的澄清和那些不太了解Swift协议的说明,这里的要点是,在Numeric Type中声明的方法已经由声明了一致性的每个类型实现。例如,因为Int类型已经实现了......
func +(lhs: Self, rhs: Self) -> Self
... NumericType协议中不需要进一步的实现细节。
在这种情况下,协议声明的目的不是为其任何实现类型添加新方法,而是提供统一的外观,允许编译器知道实现NumericType的任何内容都支持完整的Swift数学运算符集。 。因为添加了NumericType一致性的每个类型已经实现了NumericType中的所有方法,所以它们完全符合协议所需要的就是声明它们符合......
extension Int : NumericType { }