if let a = b, a.something() else



我这里有一个代码片段可以工作,但我很好奇是否有更干净的方法来完成同样的事情。到目前为止,我还没有看到完全像这样的东西。

我想要实现的逻辑

  • errornil或不是SpecialError
  • errornon-nil.foo()返回false

法典

enum SpecialError: Error {
func foo() -> Bool
}
let error: Error? // Some optional Error is passed in
if let myError = error as? SpecialError, myError.foo() {
// Don't care about this case
} else {
// This is the case I'm interested in
bar()
}

我很好奇是否有更好的方法来完成这个if let else逻辑。

我可能是误解,但似乎if语句的第一个分支什么都没有发生,您想将其缩减为第二部分? 在这种情况下,这应该适合您:

if !((error as? SpecialError)?.foo() ?? false) {
bar()
}

这将执行bar()如果:
1.error为 nil
2。error不是SpecialError
3。foo()返回假

所需的条件是表达式(error as? SpecialError)?.foo()计算结果
为:

  1. nil,在这种情况下,error不是SpecialError,或者nil
  2. false,在这种情况下errorSpecialError,但foo()返回false

在您的情况下,表达这一点的一种方法是利用等式运算符对可选项重载的事实,并说:

if (error as? SpecialError)?.foo() != true {
bar()
}

由于我们使用比较可选!=的重载,true将被提升为Bool?,因此我们正在检查(error as? SpecialError)?.foo()不是.some(true),在这种情况下,这相当于检查它是.some(false)还是.none

如果我正确理解你的问题,你可能正在寻找这样的东西:

if !((error as? SpecialError)?.foo() ?? false) {

如何完全按照您的解释进行翻译:

if error == nil || !(error! is SpecialError) || !error!.foo() {
bar()
}

的短路将防止error力解开成为问题。

我认为你的代码很难阅读,约翰·蒙哥马利的代码更难阅读,我预测它将很难维护:想象一下,一年后另一个开发人员看着这段代码,问你在做什么,或者更糟糕的是,那个开发人员不能问你,因为你不再有空。想象一下,即使几个月后你自己也会看到这段代码。

if let myError = error as? SpecialError, myError.foo()是错综复杂的,也许有点太聪明了。它包含太多的逻辑,开发人员团队无法长期阅读。

您的第一个块可以检查myError是否为零

您的第二个块可以检查是否是特殊错误类型的myError

//you could use a guard statement here
if myError == nil {
return;
}
if let myError = error as? SpecialError {
//ok myError is type SpecialError it has a foo method I can call
if(myError.foo()) {
//do something
} else {
//do something else
}
} else { //myError not type SpecialError and is not nil
// This is the case I'm interested in
bar()
}
if let theFoo = (error as? SpecialError)?.foo(){
if theFoo != true{
bar()
} //in case you want to do handling if theFoo is true
} //in case you want to do handling if error is not SpecialError

相关内容

最新更新