Swift将NSNumber的对象转换为Double

时间:2014-12-03 18:29:12

标签: ios swift

我在Swift中有这个代码并且它有效,但我认为有更好的方法从NSNumber获取我的对象并将其转换为Double:

var rating: NSNumber
var ratingDouble: Double

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

ratingDouble = Double(rating.doubleValue)

1 个答案:

答案 0 :(得分:58)

<强>更新

Swift在这里的行为自1.0以来发生了很大变化。并不是说之前那么容易,但是Swift使得在数字类型之间进行转换变得更加困难,因为它希望你明确知道如何处理精度损失。您现在的新选择如下:

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. 这会调用Double._forceBridgeFromObjectiveC根据Double(exactly:)中存储的类型调用Double Int64UInt64rating 。如果数字不能完全表示为Double,它将失败并使应用程序崩溃。例如。 UInt64.max的数字比Double可以存储的数字更多,因此会崩溃。

  2. 这与1完全相同,只是它可能会在NaN上崩溃,因为不包括该检查。

  3. 此函数始终返回Double但在1和2崩溃的情况下将失去精确度。 This literally just calls doubleValue when passing in an NSNumber.

  4. 与3相同。

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

  6. 与5相同,但如果值为NaN,则2将返回nil。

  7. 如果你知道你的数据源处理的是双打,1-4可能会为你提供相同的服务。 3和4将是我的第一选择。


    Swift 1和2的旧答案

    你可以做几件事:

    var rating: NSNumber
    var ratingDouble: Double
    
    ratingDouble = rating as Double   // 1
    ratingDouble = Double(rating)     // 2
    ratingDouble = rating.doubleValue // 3
    
    1. 第一项利用Objective-C桥接功能,允许AnyObjectNSNumber投射为Double|Float|Int|UInt|Bool
    2. 第二项可能是通过签名为init(_ number: NSNumber)的构造函数。我在模块或文档中找不到它,但是传递AnyObject生成了一个错误,它无法隐式向下转换为NSNumber所以它必须存在而不仅仅是桥接。
    3. 第三项不以相同方式使用语言功能。它只是利用doubleValue返回Double
    4. 这一事实

      1的一个好处是它也适用于AnyObject,因此您的代码可以是:

      let ratingDouble = self.prodResult!.prodsInfo.prodList[indexPath.row].avgRating! as Double
      

      请注意,我从您的函数中删除了?并移动了!。无论何时使用!你正在避免?的安全,所以没有理由一起做这两件事。