【问题标题】:Why my Swift app throws a fatal error when I try to unwrap the optional?为什么当我尝试解开可选项时,我的 Swift 应用程序会引发致命错误?
【发布时间】:2018-04-24 03:37:39
【问题描述】:

我有一个尝试过滤的数组(它是可选的)。在该数组内部有一些自定义结构的实例。他们有一个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 (Float(restaurant.distance)!)

它也会引发错误。所以,我认为问题与将字符串值转换为浮点数有关,但distance 的值只是一个数字。当我在控制台上打印它时,它看起来像这样:Optional(10999.795970332603)

所以,我不知道 Xcode 会抱怨什么。你有什么建议吗?

【问题讨论】:

  • 你如何设置restaurant.distance? "Optional(" 可能是字符串的一部分,因此它不能从中创建浮点数
  • @dan,是的,你是对的。我通过找到两个位置之间的距离来得到它。为了保存它,我将它的类型更改为 String,但 String 的初始化程序在数字前面添加了“可选(”)。

标签: arrays swift filtering


【解决方案1】:

基本上你正在崩溃,因为你告诉 Swift 崩溃如果有东西是 nil 强制解包 !

为什么你会得到nil 我不能说,因为该值可以成功转换为Float;也许它在其他一些数据上崩溃了,或者字符串实际上是Optional(10999.795970332603) - 在这种情况下,您在没有正确解包值的情况下创建该字符串值的其他地方遇到问题。

假设restaurant.distance 实际上是一个可选字符串(即String?)而不是包含Optional(10999.795970332603) 的字符串,您应该防御性地编码并使用条件展开。

您可能还想使用Double 而不是FloatFloat 只有 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
 })

【讨论】:

    【解决方案2】:

    如果您的restaurant.distance 是可选字符串,编译器会抛出一个错误,即无法使用String? 类型形成浮点数,因为您没有在Float(restaurant.distance)! 中解包restaurant.distance。但它并没有让我认为字符串本身被存储为Optional(10999.795970332603),就像丹在你的问题的 cmets 中指出的那样。将其更改为保存一个有效数字,该数字将转换为Float。你会像 Paulw11 指出的那样失去精确度,但至少它不会崩溃。并尝试使用if let 而不是强制展开,以避免在找到 nil 时崩溃。

    【讨论】:

    • 是的,你是对的。我通过查找两个位置之间的距离得到distance。为了保存它,我将它的类型更改为 String,但是 String 的初始化程序在数字前面添加了“Optional(”的东西。也许那是 String 的新初始化程序 init(describing:),因为我与 distance(from:) 方法有距离?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-18
    • 1970-01-01
    • 2019-06-23
    相关资源
    最近更新 更多