可选链接让我们可以决定是否存在对象:
var text : String?
let len = text?.lengthOfBytes(using: .utf8) ?? 0
始终将len
设置为整数。
非可选函数参数是否类似?考虑以下示例,使用三元运算符已经不那么优雅了。
func length(text: String) -> Int {
return text.lengthOfBytes(using: .utf8)
}
var text : String?
let len = (text != nil) ? length(text!) : 0
如果我们继续链接,很容易弄得一团糟(这就是我实际看到的):
let y = (arg!= nil) ? (foo?.bar(arg!) ?? 0) : 0 // how to improve on this?
此外,它也开始变得多余,定义了两次默认值。
最后一行有没有更简洁的解决方案?
答案 0 :(得分:1)
map
方法是最好的方法。 flatMap
也可能很有趣。
func length(text: String) -> Int {
return text.lengthOfBytes(using: .utf8)
}
var text : String?
let len = text.map(length) ?? 0
如果有多个参数,则可以很容易地编写一个函数(A?, B?) -> (A, B)?
。
答案 1 :(得分:0)
考虑到??
的使用会对编译时间产生影响。
在您描述的示例中,我个人喜欢使用明确使用的扩展名。
extension Optional where Wrapped == String {
func unwrappedLengthOfBytes(using: String.Encoding) -> Int {
guard let text = self else {
return 0
}
return text.lengthOfBytes(using: .utf8)
}
}
用法:
var text : String?
text.unwrappedLengthOfBytes(using: .utf8)
答案 2 :(得分:0)
您不必将自己限制为可选链接。 Swift提供了其他语言结构来清楚地表达这一点:
let y: Int
if let arg = arg, let foo = foo {
y = foo.bar(arg)
} else {
y = 0
}