Swift将NSNumber的对象转换为Double

Bry*_*imo 24 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)
Run Code Online (Sandbox Code Playgroud)

Bri*_*kel 60

更新

自1.0以来,Swift的行为发生了很大变化.并不是说之前那么容易,但是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
}
Run Code Online (Sandbox Code Playgroud)
  1. 这就要求Double._forceBridgeFromObjectiveC它调用Double(exactly:)Double,Int64UInt64基于存储的类型rating.如果数字不能完全代表,它将失败并使应用程序崩溃Double.例如,UInt64.max有多个数字Double可以存储,所以它会崩溃.

  2. 这与1完全相同,但它也可能崩溃,NaN因为不包括该检查.

  3. 此函数始终返回a Double但在1和2崩溃的情况下将失去精度. 这真的只是doubleValue在传入时调用NSNumber.

  4. 与3相同.

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

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

如果您知道您的数据源处理双打,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
Run Code Online (Sandbox Code Playgroud)
  1. 第一项利用了Objective-C允许AnyObjectNSNumber投射的桥接Double|Float|Int|UInt|Bool.
  2. 第二个项目可能是通过带签名的构造函数init(_ number: NSNumber).我无法在模块或文档中找到它,但传入AnyObject时生成了一个错误,它无法隐式向下转换,NSNumber因此它必须存在而不仅仅是桥接.
  3. 第三项不以相同的方式使用语言功能.它只是利用了doubleValue返回a 的事实Double.

1的一个好处是它也适用于AnyObject您的代码可能是:

let ratingDouble = self.prodResult!.prodsInfo.prodList[indexPath.row].avgRating! as Double
Run Code Online (Sandbox Code Playgroud)

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