Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an operator in Swift that stops the evaluation of a multi expression conditional statement, as soon as the answer is clear?

In some programming language there is two other operator in addition with simple || and &&. these operators which I am going to call them _orif and _andif from now, can be used in place of && and || and They may help to improve efficiency and avoid errors, because evaluation of the conditional stops as soon as the answer is clear.

For example, evaluation of the following expression will stop halfway through (selectedSprite != nil) is false: So the rest of the conditional will be ignored and never evaluated, this will prevent a fatal error in this case : fatal error: unexpectedly found nil while unwrapping an Optional value and it will raise while reaches to the second expression because obviously nil does not responds to SpriteOwner().

if (selectedSprite != nil) &&
   (selectedSprite.SpriteOwner().type == "Human")
{
   println("a human selected")
}

I am looking for a replacement for && in above piece of code that could be used instead of the simple && operator, So if the first expression is evaluated as a false one (having the selectedSprite equal to nil) then the second expression be ignored at all.(since it does not have any influence on result)

Question:

Is there such a &&? operator in swift? if the answer is a No,

Is there a better way of doing that instead of nested if statements like I have written here :

if (selectedSprite != nil)
{
    if (selectedSprite.SpriteOwner().type == "Human")
    {
       println("a human selected")
    }
}

I am implementing an intelligent system with a lot of if clause in it and most of them are too complicated which adding a new if layer just to control nils is a real nightmare.

like image 669
Iman Avatar asked Dec 18 '22 23:12

Iman


2 Answers

What you described is called short circuiting and Swift does have it. For example:

let a : Int? = nil

if a != nil && a! == 1 {
    print("a is 1")
} else {
    print("a is nil")
}

You can see a is never unwrapped. I think in your case, it's more likely that SpriteOwner() returns nil. the Swifty way to unwrap optional values is to use the let ... where ... syntax:

if let s = selectedSprite where s.SpriteOwner().type == "Human" {
    println("a human selected")
}
like image 136
Code Different Avatar answered Feb 01 '23 22:02

Code Different


The binary logical || and && operators in Swift 2 already behave as you describe. See "The Swift Programming Language", under "Logical AND Operator" : https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/BasicOperators.html#//apple_ref/doc/uid/TP40014097-CH6-ID60

If either value is false, the overall expression will also be false. In fact, if the first value is false, the second value won’t even be evaluated, because it can’t possibly make the overall expression equate to true. This is known as short-circuit evaluation.

Try executing the following in a playground; you will see that the second part of the conditional statement is never executed since the first part is false:

func isBar(rv: Bool) -> Bool {
    print("side effect of isBar")
    return rv
}

func isFoo() -> Bool {
    print("side effect of isFoo")
    return true
}

if isBar(false) && isFoo() {
    print("both true")
}
like image 21
matts Avatar answered Feb 01 '23 23:02

matts