将NSNumber的对象快速转换为Double [英] Swift convert object that is NSNumber to Double
问题描述
我在Swift中有这段代码并且可以正常工作,但是我认为有更好的方法从NSNumber中获取对象并将其转换为Double:
I have this code in Swift and it works, but I would think there is a better way to get my object from NSNumber and convert it to a Double:
var rating: NSNumber
var ratingDouble: Double
rating = self.prodResult?.prodsInfo.prodList[indexPath.row].avgRating as NSNumber!!
ratingDouble = Double(rating.doubleValue)
推荐答案
更新
自1.0开始,Swift的行为已发生了很大变化.以前并不是那么容易,但是Swift使得在数字类型之间进行转换变得更加困难,因为它希望您清楚地知道如何处理精度损失.现在,您的新选择如下所示:
Swift's behavior here has changed quite a bit since 1.0. Not that it was that easy before, but Swift has made it harder to convert between number types because it wants you to be explicit about what to do with precision loss. Your new choices now look like this:
var rating: NSNumber
var ratingDouble: Double
ratingDouble = rating as! Double // 1
ratingDouble = Double(exactly: rating)! // 2
ratingDouble = Double(truncating: rating) // 3
ratingDouble = rating.doubleValue // 4
if let x = rating as? Double { // 5
ratingDouble = x
}
if let x = Double(exactly: rating) { // 6
ratingDouble = x
}
-
这将调用
Double._forceBridgeFromObjectiveC
,它根据rating
中的存储类型用Double
,Int64
或UInt64
调用Double(exactly:)
.如果数字不能完全表示为Double
,它将失败并使应用程序崩溃.例如.UInt64.max
的位数超过了Double
可以存储的位数,因此会崩溃.
This calls
Double._forceBridgeFromObjectiveC
which callsDouble(exactly:)
withDouble
,Int64
, orUInt64
based on the stored type inrating
. It will fail and crash the app if the number isn't exactly representable as aDouble
. E.g.UInt64.max
has more digits thanDouble
can store, so it'll crash.
这与1完全相同,除了它可能还会在NaN
上崩溃,因为不包括该检查.
This is exactly the same as 1 except that it may also crash on NaN
since that check isn't included.
此函数始终返回Double
,但是在1和2崩溃的情况下将失去精度. 在传递时,这实际上只是调用doubleValue
在NSNumber
.
This function always returns a Double
but will lose precision in cases where 1 and 2 would crash. This literally just calls doubleValue
when passing in an NSNumber
.
与3相同.
这类似于1,除了不会崩溃的应用程序,它会返回nil并且不会评估语句的内部.
This is like 1 except that instead of crashing the app, it'll return nil and the inside of the statement won't be evaluated.
与5相同,但如果值为NaN
,则像2一样将返回nil.
Same as 5, but like 2 will return nil if the value is NaN
.
如果您知道数据源正在处理双倍数据,则1-4可能都会为您提供几乎相同的服务. 3和4是我的第一选择.
If you know your data source is dealing in doubles, 1-4 will probably all serve you about the same. 3 and 4 would be my first choices though.
Swift 1和2的旧答案
您可以执行以下几项操作:
There are several things you can do:
var rating: NSNumber
var ratingDouble: Double
ratingDouble = rating as Double // 1
ratingDouble = Double(rating) // 2
ratingDouble = rating.doubleValue // 3
- The first item takes advantage of
Objective-C
bridging which allowsAnyObject
andNSNumber
to be cast asDouble|Float|Int|UInt|Bool
. - The second item presumably goes through a constructor with the signature
init(_ number: NSNumber)
. I couldn't find it in the module or docs but passingAnyObject
in generated an error that it cannot be implicitly downcast toNSNumber
so it must be there and not just bridging. - The third item doesn't employ language features in the same way. It just takes advantage of the fact that
doubleValue
returns aDouble
.
1的一个好处是它也适用于AnyObject
,因此您的代码可以是:
One benefit of 1 is that it also works for AnyObject
so your code could be:
let ratingDouble = self.prodResult!.prodsInfo.prodList[indexPath.row].avgRating! as Double
请注意,我从功能中删除了?
并将其移入了其中.无论何时使用!您正在避开?
的安全性,因此没有理由将它们同时进行.
Note that I removed the ?
from your function and moved the !
in. Whenever you use ! you are eschewing the safety of ?
so there's no reason to do both together.
这篇关于将NSNumber的对象快速转换为Double的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!