我这里有一个代码片段可以工作,但我很好奇是否有更干净的方法来完成同样的事情。到目前为止,我还没有看到完全像这样的东西。
我想要实现的逻辑
error
nil
或不是SpecialError
error
non-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()
计算结果
为:
nil
,在这种情况下,error
不是SpecialError
,或者nil
。false
,在这种情况下error
是SpecialError
,但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