所以我有一个方法,其中包含3种不同类型的参数:
Int32
,Int
和Double
。因此,想法是使用泛型来最小化接口
func resetProgressBarChunks<T:Numeric>(originalIterationCount: T) {
guard let iCount = originalIterationCount as? Double else {return}
但是我已经意识到,在运行时,Int32
和Int
参数实际上会使guard let
失败。这是有道理的,只是我的一厢情愿。
但是,如果我尝试将Numeric
简单地转换为双精度,编译器将发出吠叫:
func resetProgressBarChunks<T:Numeric>(originalIterationCount: T) {
guard let iCount = Double(originalIterationCount) else {return}
不能为类型为'(T)'的参数调用类型为'Double'的初始化程序
我认为这也是有道理的,因为没有Double的初始化程序需要泛型。
所以看来我将被迫编写具有不同参数类型的3种方法。 Int32
和Int
参数类型将只转换为Double
,然后调用Double
方法。这真的是最好的方法吗?我真的希望我可以以某种方式利用Numeric
答案 0 :(得分:6)
仅出于句法说明的目的,这里有一个示例,使它成为泛型并针对所有三种类型都达到Double:
func f<T:Numeric>(_ i: T) {
var d = 0.0
switch i {
case let ii as Int:
d = Double(ii)
case let ii as Int32:
d = Double(ii)
case let ii as Double:
d = ii
default:
fatalError("oops")
}
print(d)
}
但是,这是否比重载更好?在我看来,重载要好得多,因为有了泛型,我们就让一堆不需要的类型进入了门。数字合同是谎言。 Double,Int和Int32的三重过载集会使编译器成为事实的来源。
答案 1 :(得分:4)
...,因为没有Double的初始化程序需要泛型。
那不是完全正确的。没有带有Numeric
参数的初始化程序。但是有些通用的初始化程序带有BinaryInteger
和BinaryFloatingPoint
参数,所以两个重载就足够了:
func resetProgressBarChunks<T: BinaryInteger>(originalIterationCount: T) {
let iCount = Double(originalIterationCount)
// ...
}
func resetProgressBarChunks<T: BinaryFloatingPoint>(originalIterationCount: T) {
let iCount = Double(originalIterationCount)
// ...
}
这涵盖了Double
,Int
,Int32
参数以及Float
和所有其他固定大小的整数类型。