我在Swift中有这个代码并且它有效,但我认为有更好的方法从NSNumber获取我的对象并将其转换为Double:
var rating: NSNumber
var ratingDouble: Double
rating = self.prodResult?.prodsInfo.prodList[indexPath.row].avgRating as NSNumber!!
ratingDouble = Double(rating.doubleValue)
答案 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
}
这会调用Double._forceBridgeFromObjectiveC
根据Double(exactly:)
中存储的类型调用Double
Int64
,UInt64
或rating
。如果数字不能完全表示为Double
,它将失败并使应用程序崩溃。例如。 UInt64.max
的数字比Double
可以存储的数字更多,因此会崩溃。
这与1完全相同,只是它可能会在NaN
上崩溃,因为不包括该检查。
此函数始终返回Double
但在1和2崩溃的情况下将失去精确度。 This literally just calls doubleValue
when passing in an NSNumber
.
与3相同。
这就像1,除了不会崩溃应用程序,它将返回nil并且不会评估语句的内部。
与5相同,但如果值为NaN
,则2将返回nil。
如果你知道你的数据源处理的是双打,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
Objective-C
桥接功能,允许AnyObject
和NSNumber
投射为Double|Float|Int|UInt|Bool
。init(_ number: NSNumber)
的构造函数。我在模块或文档中找不到它,但是传递AnyObject
生成了一个错误,它无法隐式向下转换为NSNumber
所以它必须存在而不仅仅是桥接。doubleValue
返回Double
。 1的一个好处是它也适用于AnyObject
,因此您的代码可以是:
let ratingDouble = self.prodResult!.prodsInfo.prodList[indexPath.row].avgRating! as Double
请注意,我从您的函数中删除了?
并移动了!
。无论何时使用!你正在避免?
的安全,所以没有理由一起做这两件事。