一步可选链接?

Optional Chaining in one step?

为什么这样做(示例 1):

if let numString:String = Model.selectedLocation?.zip{
        let callString:String = String(format:"tel:%@",numString)
        //more code here
    }

但不是这个(示例 2):

if let numString:String = String(format:"tel:%@",Model.selectedLocation?.zip){
        //more code here
    }

在第二个示例中,Xcode 抛出错误并希望 zip 像这样展开: String(format:"tel:%@",(Model.selectedLocation?.zip)!)
但如果我这样做,当 zip 为 nil 时应用程序将崩溃。

问题: 有没有办法让上面的第二个例子工作或者不是 possible/correct?

严格来说示例 2 既不是可选绑定也不是可选链接,因为 String(format...) returns 一个非可选的 Stringformat 参数必须是非可选的,也是。

示例 1 是处理可选值的正确推荐语法。

编辑:我完全同意亚历山大的回答(除了 String(format:) returns String?

已更新

这是因为在 String(format: " ", ) 中,arguments 必须为 not-nil,因此 !

当使用 if-let 检查可选值时,语句必须 return 可选值

// Assuming Model.selectionLocation.zip is of String type
if let numberString = Model.selectedLocation?.zip {

    let formattedString = String(format:"tel:%@", numberString)

}

或使用guard

    guard let numberString = Model.selectedLocation?.zip else {
        return
    }
    let numberString = String(format:"tel:%@", numberString)
  1. 避免冗余类型注释
  2. 避免String(format:)除非你需要它。这是来自 Foundation 框架的 NSString 方法,它有几个后果:
    1. 需要Foundation导入。
    2. 它隐式地将您的 String 桥接到 NSString
    3. 它在 Swift 3 中不起作用,因为桥接是明确的。

这里的根本问题是 String(format:) returns String?(因为格式字符串可能无效)。您可以通过使用 Swift 的字符串插值来完全避免这种情况:

if let numString = Model.selectedLocation?.zip {
    let callString = "tel: \(numString)"
    //more code here
}

...或简单的连接:

if let numString = Model.selectedLocation?.zip {
    let callString = "tel: " + numString
    //more code here
}