可选的链接和聚结包括函数参数

时间:2018-01-03 11:10:08

标签: swift swift4 null-coalescing optional-chaining

可选链接让我们可以决定是否存在对象:

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?

此外,它也开始变得多余,定义了两次默认值。

最后一行有没有更简洁的解决方案?

3 个答案:

答案 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
}