【问题标题】:Optional chaining and coalescing incl. function arguments可选的链接和合并,包括。函数参数
【发布时间】:2018-06-13 01:22:01
【问题描述】:

可选链让我们决定对象的存在:

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?

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

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

【问题讨论】:

  • 我认为可选链接就足够了,关于你的情况我会说:let len = length(text: text ?? "")
  • let len = text.map(length) ?? 0
  • 使用默认参数有缺点:1) 函数调用成本可能很高,2) 它将默认值的逻辑放入该函数并远离其上下文。
  • @Eiko 只需使用 nil 合并运算符。顺便说一句,无需创建方法来获取字符串的字节数。只需获取 utf8 CharacterView yourString.utf8.count 的计数,如果您的字符串是可选的 let len = text?.utf8.count ?? 0
  • 字节数只是一个例子,根本没有理由改进第一个例子。问题是关于如何绕过函数调用,而 nil 合并似乎并没有提供解决方案。

标签: swift swift4 null-coalescing optional-chaining


【解决方案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)?

【讨论】:

    【解决方案2】:

    考虑到?? 的使用会影响编译时间。 在您描述的示例中,我个人喜欢使用易于使用的扩展。

    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)
    

    【讨论】:

    • 谢谢,有趣的想法 - 不确定这如何解决主要问题(传递可能为零的参数)。这 '??'合并工作得很好。事实上,我正在尝试提出更简洁的代码而不是辅助函数。我认为 Swift 可能也会为此提供一些东西。
    • 这在可读性方面非常具有误导性。它使它看起来像它是非可选的对象。
    【解决方案3】:

    您不必将自己局限于可选链接。 Swift 提供了其他语言结构来清楚地表达这一点:

    let y: Int
    if let arg = arg, let foo = foo {
        y = foo.bar(arg)
    } else {
        y = 0
    }
    

    【讨论】:

    • 是的,我知道 - 我刚刚习惯了合并快捷方式,并希望参数有类似的东西。
    猜你喜欢
    • 2018-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多