所以我有一个方法有3种不同类型的参数可以进来:
Int32,Int和Double.因此,我们的想法是使用泛型来最小化界面
func resetProgressBarChunks<T:Numeric>(originalIterationCount: T) {
guard let iCount = originalIterationCount as? Double else {return}
Run Code Online (Sandbox Code Playgroud)
但我已经意识到了什么,是在运行时,Int32和Int论据实际上是失败guard let.这是有道理的,这只是我的一厢情愿.
但是,如果我尝试简单地将一个Numeric转换成双精度数,编译器将会吠叫:
func resetProgressBarChunks<T:Numeric>(originalIterationCount: T) {
guard let iCount = Double(originalIterationCount) else {return}
Run Code Online (Sandbox Code Playgroud)
无法使用类型为"(T)"的参数调用类型为"Double"的初始值设定项
我认为这也是有道理的,因为没有Double的初始化程序需要Generic.
所以看起来我将被迫用不同的参数类型编写3个方法.在Int32和Int参数的类型,将只投入Double,然后调用Double方法.这真的是最好的方式吗?我真的希望我能Numeric以某种方式利用
...因为没有带泛型的 Double 初始化程序。
这并不完全正确。没有带Numeric参数的初始化程序。但是有通用初始化器采用BinaryInteger和BinaryFloatingPoint参数,因此两个重载就足够了:
func resetProgressBarChunks<T: BinaryInteger>(originalIterationCount: T) {
let iCount = Double(originalIterationCount)
// ...
}
func resetProgressBarChunks<T: BinaryFloatingPoint>(originalIterationCount: T) {
let iCount = Double(originalIterationCount)
// ...
}
Run Code Online (Sandbox Code Playgroud)
这包括Double, Int,Int32参数以及Float所有其他固定大小的整数类型。
仅出于语法说明的目的,这里是一个使这个为通用并且为所有三种类型到达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)
}
Run Code Online (Sandbox Code Playgroud)
但这是否比重载更好是一个意见问题.在我看来,重载要好得多,因为通用我们在门上放了一堆不需要的类型.数字合同是谎言.Double,Int和Int32的三重过载将使编译器成为真实的来源.