有没有办法将任何通用数字转换为Double?

A O*_*A O 6 generics swift

所以我有一个方法有3种不同类型的参数可以进来:

Int32,IntDouble.因此,我们的想法是使用泛型来最小化界面

func resetProgressBarChunks<T:Numeric>(originalIterationCount: T) {
    guard let iCount = originalIterationCount as? Double else {return}
Run Code Online (Sandbox Code Playgroud)

但我已经意识到了什么,是在运行时,Int32Int论据实际上是失败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个方法.在Int32Int参数的类型,将只投入Double,然后调用Double方法.这真的是最好的方式吗?我真的希望我能Numeric以某种方式利用

Mar*_*n R 9

...因为没有带泛型的 Double 初始化程序。

这并不完全正确。没有带Numeric参数的初始化程序。但是有通用初始化器采用BinaryIntegerBinaryFloatingPoint参数,因此两个重载就足够了:

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所有其他固定大小的整数类型。


mat*_*att 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)
}
Run Code Online (Sandbox Code Playgroud)

但这是否比重载更好是一个意见问题.在我看来,重载要好得多,因为通用我们在门上放了一堆不需要的类型.数字合同是谎言.Double,Int和Int32的三重过载将使编译器成为真实的来源.

  • 这是一个非常糟糕的主意,因为可以添加更多符合“Numeric”的类型(来自标准库或来自第三方)。最好为符合“Numeric”的每个已知类型添加具体重载。然后,当尝试传入 switch 语句中未处理的类型时,您将不会收到“fatalError”。这不应该是公认的答案。 (2认同)