ios Swift 将 NSNumber 对象转换为 Double
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27279032/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Swift convert object that is NSNumber to Double
提问by Bryan Cimo
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)
回答by Brian Nickel
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:
自 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
}
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
.
这就要求
Double._forceBridgeFromObjectiveC
它调用Double(exactly:)
与Double
,Int64
或UInt64
基于存储的类型rating
。如果数字不能完全表示为Double
. 例如UInt64.max
,数字比Double
可以存储的多,所以它会崩溃。这与 1 完全相同,只是它也可能崩溃,
NaN
因为不包括该检查。这个函数总是返回 a
Double
但在 1 和 2 崩溃的情况下会失去精度。 这实际上只是doubleValue
在传入NSNumber
.与 3 相同。
这与 1 类似,只是它不会使应用程序崩溃,而是返回 nil 并且不会评估语句的内部。
与 5 相同,但如果值为 ,则 2 将返回 nil
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.
如果您知道您的数据源正在处理双打,那么 1-4 可能都会为您提供相同的服务。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
- 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
.
- 第一项利用了
Objective-C
桥接的优势,它允许AnyObject
并被NSNumber
强制转换为Double|Float|Int|UInt|Bool
. - 第二项大概通过带有签名的构造函数
init(_ number: NSNumber)
。我在模块或文档中找不到它,但传入AnyObject
产生了一个错误,它不能被隐式向下转换,NSNumber
所以它必须在那里而不仅仅是桥接。 - 第三项不以同样的方式使用语言特征。它只是利用了
doubleValue
返回 a的事实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 ! you are eschewing the safety of ?
so there's no reason to do both together.
请注意,我?
从您的函数中删除了并将其移入!
。每当您使用 ! 你在回避安全,?
所以没有理由一起做。