使用guard检查nil而不隐式展开

时间:2017-01-18 10:39:56

标签: swift

我知道周围有一些类似的问题,但我找不到一个特定的问题。 我有一个请求,我想检查是否存在error密钥。它不存在一切都很好,如果不是我应该处理错误。目前,我实现如下:

if let error = json["error"] {
    // handle error
}
else {
    // handle success
}

我想在这里使用一个保护声明来使成功案例没有缩进。我提出的唯一方法是

guard json["error"] == nil else {
    let error = json["error"]!
    // handle error
} 

// handle success

但这对我来说似乎不对!还有其他方法吗?

2 个答案:

答案 0 :(得分:7)

在你的guard代码中,你必须在else块中有一个return语句。像这样......

guard json["error"] == nil else {
    let error = json["error"]!
    // handle error
    return
}

// handle success

但你是对的。不得不强行解开错误。

所以在这种情况下。我认为guard是错误的解决方案。而是使用if但从条件块返回。这消除了使用else块的需要。

if let error = json["error"] {
    print(error)
    // handle error
    return
}

// handle success...
// no need for else block. Just return from the if in the error case.

guard letif let之间的区别在于未打开的可选项作用域。

如果挡块位于挡块内,则挡块位于挡块外部。

答案 1 :(得分:1)

在Swift Evolution邮件列表中提出了您的问题的想法:

  

“警卫不让”可选绑定

     

https://forums.swift.org/t/idea-guard-not-let-optional-binding/2614

     

[相当常见]你想要检查一个可选的 是否为nil,如果不是(可能使用你现在知道的值存在)仍然保释,例如:< / p>      

guard cachedValue == nil else { return cachedValue! }
    cachedValue = //… expensive calculation

     

在检查Optional.Some时,我们有这种可爱的干净let语法似乎有点“不公平”,但我们必须在检查Optional时对nil和显式解包进行这种丑陋的手动检查。没有。实际上没有其他方法来满足守卫声明;我们的可选绑定只能单向无法评估。

不幸的是,Swift中当前不存在该构造。

替代方案是稍微笨拙/重复的guard语法,可能需要强制解包:

guard json["error"] == nil else {
    return json["error"]!
}

或使用if-let强制执行范围 - 退出,如guard):

if let error = json["error"] {
    return error
}