Syntax convention : IF ELSE statements?

Having a look online I couldn't find syntax conventions for use with IF ELSE statements, and would like to know if there are any.

e.g.

} else if {

or

}

else if {

Do you mean style conventions?

The syntax does not care about whitespace; these are all valid syntax:

if false {
    // ...
} else if true {
    // ...
}
if false {
    // ...
}
else if true {
    // ...
}
if false {
    // ...
}

else if true {
    // ...
}
if false
{
    // ...
}
else if true
{
    // ...
}

While you will see them all in different projects, the style consistently used by Swift’s own documentation is the first one.

Thank you for the clarification, do you have a link to that, or is just the style adopted throughout the example code?

The following should be proper then:

                     if (someKey == Menu.option1.rawValue) {
                                
                                if (someButtonValue is Int) {
                                    
                                    someButton.option = someButtonValue as! Int
                                }
                            } else if (someButtonKey == Menu.option2.rawValue) {
                                
                                if (someButtonValue is String) {
                                    
                                    someButton.option = someButtonValue as! String
                                }
                            }

No carriage spaces?

No, it is just adopted throughout the sample code.

There are API Design Guidelines, which have some overlap with source style, but they don’t cover this. There has been talk of adopting a recommended style guide, but it has been deferred for the time being.

i would indent that properly, also, the parentheses aren’t needed

if      someKey       == Menu.option1.rawValue
{
    if someButtonValue is Int
    {
       someButton.option = someButtonValue as! Int
    }
} 
else if someButtonKey == Menu.option2.rawValue
{
    if someButtonValue is String
    {
       someButton.option = someButtonValue as! String
    }
}

it would also be better to use an optional cast:

if      someKey       == Menu.option1.rawValue
{
    if let option:Int = someButtonValue as? Int
    {
       someButton.option = option
    }
} 
else if someButtonKey == Menu.option2.rawValue
{
    if let option:String = someButtonValue as? String
    {
       someButton.option = option
    }
}

Thanks, I completely forgot about the parentheses, I've been guided by a foreign hand and have lost my way.

Good to hear about the guidelines, I just wish the changes were automatically enforced, rather than having to cut&paste.

And Optional Casting was going to be next task, as I have a lot of nested statements i.e. Pyramid of Doom™.

...and that is a case in point. As you can see, not everyone uses the same style as the examples provided by the Swift project. :wink: And that is just fine.

This is what I’m familiar with from Swift’s own examples:

if someKey == Menu.option1.rawValue {
    if let integer = someButtonValue as? Int {
        someButton.option = integer
    }
} else if someButtonKey == Menu.option2.rawValue {
    if let string = someButtonValue as? String {
        someButton.option = string
    }
}

But it does the exact same thing as the alternate example above, so it really doesn’t matter too much.

Xcode can help with some things (⌃I will reindent the selection), and there are various third party tools out there that can do even more. Just search the internet for “swift” and “format”.

1 Like

Personally, as a bit of an oldie, I always prefer symmetric braces. Just for the record, that code can be written with composite ifs:

if someKey == Menu.option1.rawValue,
   let integer = someButtonValue as? Int
{
  someButton.option = integer
}
else
{
  if someButtonKey == Menu.option2.rawValue,
     let string = someButtonValue as? String
  {
    someButton.option = string
  }
}

I don't know if you're familiar with gaming in 2D in SpriteKit, but am unsure if a Guard statement would be better than IF LET when iterating over the nodes in a scene to look for labels to display text in:

if self.camera?.childNode(withName: CurrentItem.name!) != nil {
                
                
                if let descriptionField: SKLabelNode = self.camera?.childNode(withName: "description1") as? SKLabelNode {
                    
                    if descriptionLabel1.text != nil {
                        
                        descriptionLabel1.text = "test1"
                    }
                }
                
                
                if let descriptionField: SKLabelNode = self.camera?.childNode(withName: "description2") as? SKLabelNode {
                    
                    
                    if descriptionLabel2.text != nil {
                        
                        descriptionLabel2.text = "test2"
                    }
                }

If there is no text then it's not a big issue, but as the statement exits early will that ignore subsequent checks (although I plan to put this into a loop). I don't need anything in the field if the data fetched is a nil value, so would guard be useful at all here?

Yes. return, throw and the like work the same in a guard statement as anywhere else.

These do exactly the same thing:

guard x else {
    return "Skipped"
}
doStuff()
return "Finished"
if x {
    doStuff()
    return "Finished"
} else {
    return "Skipped"
}

They have the same implications when used sequentially:

guard x else {
    return "Skipped “x”"
    // Oops! We returned before ever trying “y”.
}
doStuff()
guard y else {
    return "Skipped “y”"
}
doOtherStuff()
return "Finished both"
if x {
    doStuff()
} else {
    return "Skipped “x”"
    // Oops! We returned before ever trying “y”.
}
if y {
    doOtherStuff()
} else {
    return "Skipped “y”"
}
return "Finished both"

And they have the same implications in a loop:

for number in 1 ... 10 {
    guard x else {
        return "Skipped \(number)"
        // Oops! We returned, aborting the loop as soon as “x” was false.
    }
    doStuff()
}
for number in 1 ... 10 {
    if x {
        doStuff()
    } else {
        return "Skipped \(number)"
        // Oops! We returned, aborting the loop as soon as “x” was false.
    }
}

For an if statement to be a good candidate for refactoring as a guard, three things must hold true:

  1. It must have an else section.
  2. The else section must contain a return, throw, fatarError(), etc. that exits the scope.
  3. The else section should be shorter than the if section. (This is less important, but otherwise it usually means you would be making it harder to read instead of easier.)

One might want to adopt the swiftlint style for things like this then one never has to ask this question. @SDGGiesbrecht 's code above is most like the swiftlint style.

I thought about it but my system is slow enough as it is and I'm fed up of Xcode crashing, as well as more red and yellow stripes across all of my code!