Swift convert object that is NSNumber to Double
Update
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: NSNumbervar ratingDouble: DoubleratingDouble = rating as! Double // 1ratingDouble = Double(exactly: rating)! // 2ratingDouble = Double(truncating: rating) // 3ratingDouble = rating.doubleValue // 4if let x = rating as? Double { // 5 ratingDouble = x}if let x = Double(exactly: rating) { // 6 ratingDouble = x}
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.This is exactly the same as 1 except that it may also crash on
NaN
since that check isn't included.This function always returns a
Double
but will lose precision in cases where 1 and 2 would crash. This literally just callsdoubleValue
when passing in anNSNumber
.Same as 3.
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.
Same as 5, but like 2 will return nil if the value is
NaN
.
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.
Old Answer for Swift 1 and 2
There are several things you can do:
var rating: NSNumbervar ratingDouble: DoubleratingDouble = rating as Double // 1ratingDouble = Double(rating) // 2ratingDouble = 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
.
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.