Swift 的 pow() 函数不接受 Doubles 作为参数

标签 swift generics pow downcast type-constraints

我创建了这个 中缀运算符 ^^ 作为使用 pow 函数的替代:

infix operator ^^ { associativity left precedence 155 }
func ^^ <T: IntegerLiteralConvertible>(left: T, right: T) -> T {
    return pow(left as Double, right as Double)
}

我使用IntegerLiteralConvertible 协议(protocol)作为泛型leftright 的类型约束,因为根据我的理解this diagramm表明,它基本上包括所有数字类型。

为了使用 pow 函数,我必须将 leftright 向下转换为 Double,我确实使用了 as 运算符。这不是最安全的方法,但这不是重点。

实现函数this way时 swift 告诉我:

<stdin>:4:12: error: cannot invoke 'pow' with an argument list of type '(Double, Double)'
return pow(left as Double, right as Double)
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

据我所知,pow 需要两个 Double 作为参数,那么它为什么会提示这个呢?

最佳答案

why is it complaining about this?

因为 pow 返回 Double .和 Double不等于 T .该错误消息具有误导性,但它的意思是“无法找到接受 pow 并返回 (Double, Double) 类型的 T


我认为您误解了 Swift 中的“cast”。在 Swift 中 as不转换数值类型。

let intVal:Int = 12
let doubleVal:Double = intVal as Double
//                            ^ [!] error: 'Int' is not convertible to 'Double'

如果操作数的类型在编译时不可预测,则无效转换会导致运行时错误:

func foo<T: IntegerLiteralConvertible>(x: T)  {
    x as Double // <-- Execution was interrupted
}
foo(12 as Int)

相反,我们必须明确地“转换”它们。请参阅文档:Numeric Type Conversion

let intVal:Int = 12
let doubleVal:Double = Double(intVal)

之所以有效,是因为 Doubleinit(_ v: Int)初始值设定项。以下代码无法编译:

func foo<T: IntegerLiteralConvertible>(x: T)  {
    Double(x)
//  ^~~~~~~~~ [!] error: cannot invoke 'init' with an argument of type 'T'
}

因为 Double没有 init<T:IntegerLiteralConvertible>(_ val:T)初始化程序。

所以,如果你想使用 pow() , 你必须转换 TDouble对于参数,并转换 DoubleT用于返回值。对此没有简单的解决方案。

关于Swift 的 pow() 函数不接受 Doubles 作为参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28702782/

相关文章:

c# - 无法使用动态参数和泛型调用扩展方法

reactjs - 具有通用参数/返回类型的 Typescript React 无状态函数

c# - 实现多个泛型类型的泛型接口(interface) - 如何共享方法实现?

ios - pow() 行为与 Float 和 Double 不同

ios - 从 Firebase 数据库检索后将字符串更改为日期时值为 nil

swift - 用幻像类型解码泛型

ios - 如何链接到 xcode 7 beta 中的 libz 和 libsqlite?

ios - 如何: Format Swift UI Buttons

c++ - C/C++ 中 pow() 函数的实现是否因平台或编译器而异?