简体   繁体   English

Swift将NSNumber的对象转换为Double

[英]Swift convert object that is NSNumber to 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: 我在Swift中有这个代码并且它可以工作,但我认为有更好的方法从NSNumber获取我的对象并将其转换为Double:

var rating: NSNumber
var ratingDouble: Double

rating = self.prodResult?.prodsInfo.prodList[indexPath.row].avgRating as NSNumber!!

ratingDouble = Double(rating.doubleValue)

Update 更新

Swift's behavior here has changed quite a bit since 1.0. 自1.0以来,Swift的行为发生了很大变化。 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. 并不是说之前那么容易,但是Swift使得在数字类型之间进行转换变得更加困难,因为它希望你明确知道如何处理精度损失。 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
}
  1. This calls Double._forceBridgeFromObjectiveC which calls Double(exactly:) with Double , Int64 , or UInt64 based on the stored type in rating . 这会调用Double._forceBridgeFromObjectiveC ,它根据存储的rating类型调用Double(exactly:)DoubleInt64UInt64 It will fail and crash the app if the number isn't exactly representable as a Double . 如果数字不能完全表示为Double ,它将失败并使应用程序崩溃。 Eg UInt64.max has more digits than Double can store, so it'll crash. 例如, UInt64.max数字比Double可以存储的数字多,所以它会崩溃。

  2. This is exactly the same as 1 except that it may also crash on NaN since that check isn't included. 这与1完全相同,只是它也可能在NaN崩溃,因为不包括该检查。

  3. This function always returns a Double but will lose precision in cases where 1 and 2 would crash. 此函数始终返回Double但在1和2崩溃的情况下将失去精度。 This literally just calls doubleValue when passing in an NSNumber . 这通常只是在传入NSNumber时调用doubleValue

  4. Same as 3. 与3相同。

  5. 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. 这就像1,除了不会崩溃应用程序,它将返回nil并且不会评估语句的内部。

  6. Same as 5, but like 2 will return nil if the value is NaN . 与5相同,但如果值为NaN则2将返回nil。

If you know your data source is dealing in doubles, 1-4 will probably all serve you about the same. 如果您知道您的数据源处理双打,1-4可能都会为您提供相同的服务。 3 and 4 would be my first choices though. 3和4将是我的第一选择。


Old Answer for Swift 1 and 2 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
  1. The first item takes advantage of Objective-C bridging which allows AnyObject and NSNumber to be cast as Double|Float|Int|UInt|Bool . 第一项利用Objective-C桥接,允许AnyObjectNSNumber转换为Double|Float|Int|UInt|Bool
  2. The second item presumably goes through a constructor with the signature init(_ number: NSNumber) . 第二项可能是通过签名init(_ number: NSNumber)的构造函数。 I couldn't find it in the module or docs but passing AnyObject in generated an error that it cannot be implicitly downcast to NSNumber so it must be there and not just bridging. 我无法在模块或文档中找到它,但是在传递AnyObject时生成了一个错误,它无法隐式向下转换为NSNumber因此它必须存在而不仅仅是桥接。
  3. The third item doesn't employ language features in the same way. 第三项不以相同的方式使用语言功能。 It just takes advantage of the fact that doubleValue returns a Double . 它只是利用了doubleValue返回Double的事实。

One benefit of 1 is that it also works for AnyObject so your code could be: 1的一个好处是它也适用于AnyObject因此您的代码可以是:

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 ! in。每当你使用! you are eschewing the safety of ? 你是在避免安全? so there's no reason to do both together. 所以没有理由一起做这两件事。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM