无需重新分配变量即可展开 Swift 可选

Posted

技术标签:

【中文标题】无需重新分配变量即可展开 Swift 可选【英文标题】:Unwrapping Swift optional without variable reassignment 【发布时间】:2015-02-25 00:24:20 【问题描述】:

当使用可选绑定解包单个方法调用(或可选链接用于长方法调用链)时,语法清晰易懂:

if let childTitle = theItem.getChildItem()?.getTitle() 
    ...

但是,当提供变量作为参数时,我发现自己要么使用:

func someFunction(childTitle: String?) 
    if let theChildTitle = childTitle 
        ...
    

甚至只是用相同的名称重新定义它:

if let childTitle = childTitle ...

我开始想知道是否有一种快捷方式或更有效地执行nil 检查,其唯一目的是使用现有变量。我想象过这样的事情:

if let childTitle ...

这样的事情是否存在,或者至少是我上述两个临时解决方案的替代方案?

【问题讨论】:

【参考方案1】:

没有。您应该打开您的选项,只需使用您提到的相同名称重新定义它。这样您就不需要创建第二个 var。

func someFunction(childTitle: String?) 
    if let childTitle = childTitle 
        ...
    

更新:Xcode 7.1.1 • Swift 2.1

你也可以使用如下守卫:

func someFunction(childTitle: String?) 
    guard let childTitle = childTitle else 
        return
    

    // childTitle it is not nil after the guard statement
    print(childTitle)

【讨论】:

我知道这一点,并在我的问题中提到它 - 但是,我想知道是否有 "... at least an alternative to my above two interim solutions?" @craig 抱歉没有注意到 BTW 那是推荐的方法。忘记其他的 我没有看到任何其他解决方案。您可以将参数用作可选参数,但如果您要编写的代码需要一个不可空值,则必须使用可选绑定。希望 Apple 能在 Swift 1.2+ 中改善这种情况 有趣的是,您可以重复使用相同的名称。显然这被称为variable shadowing。 我希望 Swift 有一个特殊的关键字来让最后一个代码块不那么难看,比如... guard unwrap childTitle else【参考方案2】:

这是我知道的唯一选择。

func someFunction(childTitle: String?) 
    if childTitle != nil 
        ...
    

但是childTitle 仍然是可选的,因此每次使用时都必须打开它:childTitle!.doSomething()。不过,它不应该影响性能。

【讨论】:

【参考方案3】:

我已经养成了重新分配相同名称的习惯。这消除了提出单独名称的需要,并避免了新名称是否应该在任何地方使用的任何混淆。但是,请注意块后的输出:

var test: String? = "123"
if var test = test 
    test += "4"
    test += "5"

print(test) // prints "123"

如果你需要在块之后访问修改后的值,你可以将变量赋给一个新的名字,并将新的名字赋回给块内的旧名字:

var test: String? = "123"
if var testWorking = test 
    testWorking += "4"
    testWorking += "5"
    test = testWorking

print(test) // prints "12345"

【讨论】:

以上是关于无需重新分配变量即可展开 Swift 可选的主要内容,如果未能解决你的问题,请参考以下文章

发现可选值错误 nil swift 3

具有 NSData 变量的领域对象,在展开可选值时意外发现 nil

在展开可选值 uint32 swift 时意外发现 nil

Swift 中的非英文字符给出:致命错误:在展开可选值时意外发现 nil

在 Swift 中,我如何避免选项和 nil 对象引用?

如何重新分配 StringBuffer 的值?