i am trying to do following:-
var isSomeThingTrue = checkSomeThing()
if (let someOptional = getSomeOptional(),
let anotherOptional = getAnotherOptional(withSomeOptional: someOptional)) ||
isSomeThingTrue {
// do something
} else {
// do something else
}
Is there a way this could be achieved with if statement or i have to use a guard statement ?
CodePudding user response:
The whole point of the if let x = y
syntax is that the if block is only run if y
is not nil, so you can bind it to a non-optional let-constant x
, and x
can be used inside the if block.
However, in your case, the if block can still be run even if getSomeOptional()
returns nil, but isSomeThingTrue
is true. So in the if block, you don't know if getSomeOpional
returned nil or not. someOptional
still has to be of an optional type. The same goes for anotherOptional
.
Therefore, you don't need if let
to do this, just do:
// unlike with the 'if let', these let constants are visible are in scope outside the if statement too
// if you don't like that for some reason, wrap the whole thing with a do { ... } block
let someOptional = getSomeOptional()
let anotherOptional = getAnotherOptional(withSomeOptional: someOptional)
if (someOptional != nil && anotherOptional != nil) || isSomeThingTrue {
// do something
} else {
// do something else
}
If getAnotherOptional
takes a non-optional, use flatMap
:
let anotherOptional = someOptional.flatMap(getAnotherOptional(withSomeOptional:))
CodePudding user response:
I guess there are many ways to skin this cat so here is one more, if you move the code to be executed inside the if
into a function to avoid code duplication the below way is in my option easy to read
if let someOptional = getSomeOptional(), let anotherOptional = getAnotherOptional(withSomeOptional: someOptional) {
doSomething(anotherOptional)
} else if checkSomeThing() {
doSomething(nil)
} else {
// do something else
}