【问题标题】:How to correctly do Nil Coalescing in Swift?如何在 Swift 中正确进行 Nil Coalescing?
【发布时间】:2016-06-20 06:50:15
【问题描述】:

应该这样做

var inputField =  UITextField()
let defaultText = "PLACEHOLDER"
let newText = inputField.text!.isEmpty ? defaultText : inputField.text!
let newText2 = inputField.text ?? defaultText

newText 工作,并输出PLACEHOLDER

newText 仅在 Swift 的预览列中显示 ""

为什么?怎么弄好?

【问题讨论】:

  • text属性的值真的是nil吗?我认为这是不一样的空字符串。

标签: swift ternary-operator ternary null-coalescing-operator null-coalescing


【解决方案1】:

""nil 之间存在很大差异。您的text 属性是,但它不是 nil。 (它实际上等于字符串 ""。)因此,您对 .isEmpty 的检查有效,但您尝试 nil coalesce 无效。另一方面,这将起作用:

let text: String? = nil
let newText2 = text ?? defaultText

所以你对 nil 合并的理解很好;您认为空文本字段返回nil 的假设不是:它实际上返回一个空字符串——但存在——字符串。

【讨论】:

    【解决方案2】:
    import UIKit
    
    var inputField =  UITextField()
    inputField.text?.isEmpty // true !!!
    // by deafault it is empty, so i set it
    inputField.text = "default text"
    
    let defaultText = "PLACEHOLDER"
    let newText = inputField.text?.isEmpty == true ? defaultText : inputField.text!
    let newText2 = inputField.text ?? defaultText
    
    print(newText)  // default text
    print(newText2) // default text
    

    在你的 sn-p newText2 中是空字符串,因为 inputField.text 不是 nil

    如何做到这一点的安全方法(inputField.text 可以是 nil、空或一些文本)

    import UIKit
    
    var inputField =  UITextField()
    let defaultText = "PLACEHOLDER"
    if let txt = inputField.text {
        inputField.text = txt.isEmpty ? defaultText : txt
    }
    
    let newText = inputField.text ?? defaultText
    
    print(inputField.text, newText) // Optional("PLACEHOLDER") PLACEHOLDER
    

    因此,如果 inputField.text 为空或 nil,则将其设置为某个默认值,否则不会更改文本

    【讨论】:

    • @LeoDabus :-) 我现在明白了,你在说什么,谢谢!我使用复制粘贴来自 OP 问题的代码...已编辑!
    【解决方案3】:

    一个更 Swift-y 的解决方案,用于检查“x 是空还是空?”是使用扩展名:

    extension Optional where Wrapped == String {
        var nilIfEmpty: String? {
            guard let strongSelf = self else {
                return nil
            }
            return strongSelf.isEmpty ? nil : strongSelf
        }
    
        var isEmptyOrNil: Bool {
            guard let strongSelf = self else {
                return true
            }
            return strongSelf.isEmpty
        }
    }
    

    let newText2 = inputField.text ?? defaultText 失败的原因是因为默认情况下inputField.text = "" 不属于 nil-coalescing 运算符的nil 情况(如Optional("") != nil)。


    您可以使用这些Optional<String> 扩展来替换:

    let newText = inputField.text!.isEmpty ? defaultText : inputField.text!
    let newText2 = inputField.text ?? defaultText
    

    let newText = inputField.text.isEmptyOrNil ? defaultText : inputField.text! 
    let newText2 = inputField.text.nilIfEmpty ?? defaultText
    

    两者都可以正常工作。虽然我建议安全地展开 inputField.text 而不是使用 ! 运算符(尽管这在技术上是安全的,但我尽量避免使用 bang 运算符) - 因此使用 nilIfEmpty 的 nil-coalescing 解决方案更可取。

    此外,您可以使用后者来防止在 if 语句和三元运算中出现常见(和混乱)someOptionalString?.isEmpty ?? true 舞蹈,如:

    if someOptionalString.isEmptyOrNil {
        // Do something when a string is empty or nil...
    }
    

    干净得多
    if someOptionalString?.isEmpty ?? true {
        // Do something when a string is empty or nil...
    }
    

    【讨论】:

      猜你喜欢
      • 2017-09-05
      • 1970-01-01
      • 2016-11-16
      • 1970-01-01
      • 2015-03-02
      • 1970-01-01
      • 2019-08-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多