Swift的pow()函数不会接受Doubles作为参数 [英] Swift's pow() function won't accept Doubles as arguments

查看:398
本文介绍了Swift的pow()函数不会接受Doubles作为参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了这个infix operator ^^来代替使用pow函数:

I created this infix operator ^^ as a substitute to using the pow function:

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

我将IntegerLiteralConvertible协议用作泛型leftright的类型约束,因为据我了解,此图表显示,它基本上包括所有数字类型.

I used the IntegerLiteralConvertible protocol as a type constraint for the generics left and right, because from my understanding this diagramm shows, that it basically includes all number types.

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

In order to use the pow function I have to downcast left and right to Double though, which I did using the as operator. It's not the safest approach, but that's besides the point.

在实现功能时以此方式 swift告诉我:

When implementing the function this way swift tells me:

<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作为参数,那么为什么会抱怨呢?

Now as far as I know pow takes two Doubles as parameters, so why is it complaining about this?

推荐答案

为什么要抱怨呢?

why is it complaining about this?

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

Because pow returns Double. And Double is not identical to T. The error message is misleading, but it means "Cannot find pow that accepts (Double, Double) and returns T type"

我认为您在Swift中误解了"cast".在Swift中,as不会转换数字类型.

I think you are misunderstanding "cast" in Swift. In Swift as does not convert numeric types.

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

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

And If the type of operand is not predictable at compile time, invalid casting causes runtime error:

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

相反,我们必须明确地转换"它们.请参阅文档:数值类型转换

Instead, we must explicitly "convert" them. see the document: Numeric Type Conversion

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

这仅因Double具有init(_ v: Int)初始化程序而起作用.以下代码无法编译:

This works only because Double has init(_ v: Int) initializer. The following code does not compile:

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(),则必须将T转换为Double作为参数,并将Double转换为T以返回值.而且没有简单的解决方案.

So, if you want to use pow(), you must convert T to Double for arguments, and convert Double to T for returning value. And there is no simple solution for that.

这篇关于Swift的pow()函数不会接受Doubles作为参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆