Type 应该采用啥协议来让泛型函数将任何数字类型作为 Swift 中的参数?
Posted
技术标签:
【中文标题】Type 应该采用啥协议来让泛型函数将任何数字类型作为 Swift 中的参数?【英文标题】:What protocol should be adopted by a Type for a generic function to take any number type as an argument in Swift?Type 应该采用什么协议来让泛型函数将任何数字类型作为 Swift 中的参数? 【发布时间】:2014-10-23 21:25:24 【问题描述】:我想让一个函数在 Swift 中接受任何数字(Int、Float、Double、...)
func myFunction <T : "What to put here"> (number : T) ->
//...
不使用 NSNumber
【问题讨论】:
【参考方案1】:更新: 下面的答案原则上仍然适用,但 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
【讨论】:
谢谢你,这么好的答案! 是的,这比在***.com/a/28457725/466698 中实现所有自己的运算符要好得多,为什么 Swift 本身不包含这样的协议? 一些谨慎。 NumericType,在此处实现,作为 Self 要求。因此,您将无法执行 var values = [NumericType] 之类的操作。如果你想这样做,你必须提供自己的运营商,唉。 使用这种方法有没有办法将T
转换为Int
?喜欢Int(number)
?或者使用其他功能,如floor(number)
?
在 Swift 4 中,Numeric 协议定义了除 '/' 和 '%' 之外的所有操作符。该协议由浮点和整数类型实现。【参考方案2】:
作为与评论打击相关的澄清以及对于那些不太了解 Swift 协议的人来说,这里的重点是在 Numeric Type 中声明的方法已经由已声明一致性的每个类型实现。例如,因为 Int 类型已经实现了...
func +(lhs: Self, rhs: Self) -> Self
...在 NumericType 协议中不需要进一步的实现细节。
在这种情况下,协议声明的目的不是为它的任何实现类型添加新方法,而是提供一个统一的外观,让编译器知道任何实现 NumericType 的东西都支持全套 Swift 数学运算符.因为每个添加了 NumericType 一致性的类型已经实现了 NumericType 中的所有方法,所以它们完全符合协议所需要做的就是声明它们符合...
extension Int : NumericType
【讨论】:
以上是关于Type 应该采用啥协议来让泛型函数将任何数字类型作为 Swift 中的参数?的主要内容,如果未能解决你的问题,请参考以下文章