将NSNumber的对象快速转换为Double [英] Swift convert object that is NSNumber to Double

查看:275
本文介绍了将NSNumber的对象快速转换为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
}

  1. 这将调用 Double._forceBridgeFromObjectiveC ,它根据rating中的存储类型用DoubleInt64UInt64调用Double(exactly:).如果数字不能完全表示为Double,它将失败并使应用程序崩溃.例如. UInt64.max的位数超过了Double可以存储的位数,因此会崩溃.

  1. This calls Double._forceBridgeFromObjectiveC which calls Double(exactly:) with Double, Int64, or UInt64 based on the stored type in rating. It will fail and crash the app if the number isn't exactly representable as a Double. E.g. UInt64.max has more digits than Double 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崩溃的情况下将失去精度. 在传递时,这实际上只是调用doubleValueNSNumber.

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

  1. 第一项利用Objective-C桥接功能,允许AnyObjectNSNumber强制转换为
  1. The first item takes advantage of Objective-Cbridging which allows AnyObject and NSNumber to be cast as Double|Float|Int|UInt|Bool.
  2. 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 passing AnyObject in generated an error that it cannot be implicitly downcast to NSNumber so it must be there and not just bridging.
  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.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆