为什么我的Swift应用程序在尝试打开可选项时会抛出致命错误?
我有一个数组(它是可选的),我尝试过滤。该数组内部有一些自定义结构的实例。他们有一个distance
财产,这是一个String
。现在,过滤数组的条件是这些字符串应该小于或等于某个浮点值(distance
)。下面是代码:为什么我的Swift应用程序在尝试打开可选项时会抛出致命错误?
filteredUnitRestaurants = anotherUnitRestaurant?.filter({ (restaurant) -> Bool in
print (restaurant.distance)
return Float(restaurant.distance)! <= Float(distance)
})
当我实现它,Xcode中抛出一个错误,它说,它意外地发现零而展开的可选值(一个布尔表达式的线)。然而,print
方法打印distance
值,所以它不是零,但是当我改变这样的打印语句:
print (Float(restaurant.distance)!)
它抛出一个错误,太。所以,我认为问题与将字符串值转换为浮点数有关,但distance
的值只是一个数字。当我在控制台上打印它时,它看起来像这样:Optional(10999.795970332603)
所以,我不知道Xcode会发生什么抱怨。你有什么建议吗?
如果您restaurant.distance
是一个可选的字符串,编译器会引发错误的浮标不能与类型String?
,因为你不是在Float(restaurant.distance)!
展开restaurant.distance
形成。但它并没有让我认为这个字符串本身被存储为Optional(10999.795970332603)
,就像丹在你的问题的评论中指出的那样。更改该值以保存通过转换为Float
的有效数字。像Paulw11指出的那样,你会失去精确性,但至少它不会崩溃。并尝试使用if let
而不是强制展开,以避免发现零时崩溃。
是的,你说得对,我通过找到两个位置之间的距离来得到'distance',为了保存它,我改变它的类型为String,但是String的初始化方法增加了“Optional(”在数字前面的东西,也许这就是String的新的初始化'init(描述:)),因为我距离'distance(from:)'method? –
基本上,你正在崩溃,因为你告诉斯威夫特崩溃如果是nil
强行展开!
。
为什么你得到nil
我不能说,因为该值可以成功地转换为Float
;也许它会崩溃在其他一些数据上,或者字符串可能是字面意思Optional(10999.795970332603)
- 在这种情况下,如果没有正确解开值,您在创建该字符串值的其他地方出现问题。
假设restaurant.distance
实际上是一个可选字符串(即String?
)而不是包含Optional(10999.795970332603)
的字符串,您应该防御性地编码并使用条件解包。您可能还想使用Double
而不是Float
。 A Float
只有32位,你正在失去很多的精度; 10999.795970332603作为Float
是10999.8,而作为Double
是10999.7959703326。
最后,在过滤之前,将distance
转换为Double
;你正在做不必要的工作每次将其转换
let doubleDistance = Double(distance)
filteredUnitRestaurants = anotherUnitRestaurant?.filter({ (restaurant) -> Bool in
guard let distanceStr = restaurant.distance,
let restaurantDistance = Double(distanceStr) else {
return false
}
return restaurantDistance <= doubleDistance
})
你如何设置'restaurant.distance'? “可选(”可能是字符串的一部分,所以它不能从它创建一个Float。 – dan
@dan,是的你是对的,我通过找到两个位置之间的距离来得到它。为了保存它,我将它的类型更改为String,但String的初始化程序添加了“Optional(”前面的数字 –