我有一个数组(它是可选的)我尝试过滤。在该数组内部有一些自定义结构的实例。它们的distance
属性为String
。现在,过滤数组的条件是这些字符串应小于或等于某个浮点值(distance
)。这是代码:
filteredUnitRestaurants = anotherUnitRestaurant?.filter({ (restaurant) -> Bool in
print (restaurant.distance)
return Float(restaurant.distance)! <= Float(distance)
})
当我实现它时,Xcode会抛出一个错误,它表示在展开Optional值时(在布尔表达式的行中)意外地发现了nil。但是,print
方法打印distance
值,因此它不是nil,但是当我像这样更改print语句时:
print (Float(restaurant.distance)!)
它也会引发错误。所以,我认为问题与将字符串值转换为float有关,但distance
的值只是一个数字。当我在控制台上打印它时,它看起来像这样:Optional(10999.795970332603)
所以,我不知道是什么让Xcode抱怨。你有什么建议吗?
答案 0 :(得分:3)
如果您的restaurant.distance
是一个可选字符串,编译器会抛出一个错误,即无法使用String?
类型形成Float,因为您不能将restaurant.distance
解包Float(restaurant.distance)!
。但它没有让我认为字符串本身被存储为Optional(10999.795970332603)
,就像你在问题的评论中指出的那样。将其更改为保存将转换传递给Float
的有效数字。你会像Paulw11指出的那样失去精确度,但至少它不会崩溃。并尝试使用if let
而不是强制解包,以避免在找到nil时崩溃。
答案 1 :(得分:2)
基本上你是因为告诉Swift崩溃,如果nil
通过!
强行解包而导致崩溃
为什么你得到nil
我不能说,因为该值可以成功转换为Float
;也许它正在崩溃其他一些数据,或者字符串可能是Optional(10999.795970332603)
- 在这种情况下,你在其他地方有一个问题,你正在创建该字符串值而没有正确地解包值。
假设restaurant.distance
实际上是一个可选字符串(即。String?
)而不是包含Optional(10999.795970332603)
的字符串,您应该采取防御性编码并使用条件解包。
您可能还想使用Double
代替Float
。 Float
只有32位,你会失去很多精度;作为Float
的10999.795970332603是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
})