Swift的pow()函数不会接受Doubles作为参数 [英] Swift's pow() function won't accept Doubles as arguments
问题描述
我创建了这个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
协议用作泛型left
和right
的类型约束,因为据我了解,此图表显示,它基本上包括所有数字类型.
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
函数,我必须将left
和right
向下转换为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 Double
s as parameters, so why is it complaining about this?
推荐答案
为什么要抱怨呢?
why is it complaining about this?
因为pow返回Double
.并且Double
与T
不同.该错误消息具有误导性,但是它的意思是无法找到接受(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屋!