Guard testing nil in condition -> autounboxing in else


The guard syntax is super, but I'm missing an autounboxing in the else path, if the condition is testing for nil. It would be nice, if the compiler could autounbox this optional in the else path.

func something() -> Error? { ... }

func foo() {
    let error = something()
    guard error == nil else {
        print(error) //currently, you have to explicit write print(error!), even error will never be nil

guard is just an inverted if. When the error needs to be available (for throwing or logging), guard is the wrong tool.

if let error = something() {

I have run into the same issue multiple times, and I've concluded that trying to make every scenario fit into a specific style of code or a particular construction is just fighting the language for pointless consistency.

This is not completely true. Guard statements are not simply inverted if statements.

From the Swift Reference Manual:

The else clause of a guard statement is required, and must either call a function with the Never return type or transfer program control outside the guard statement’s enclosing scope using one of the following statements:

  • return
  • break
  • continue
  • throw

Of course they don't behave identically, otherwise there would be no point to having guard in the language. In the context of the OP's complaint, the guard he wants is just an inverted if. The if doesn't force an early break from the current scope, and that's the only real difference.

Yeah, if let would be the alternative.

What you're describing is called flow-sensitive typing, and you'll be able to catch up a number of previous discussions on this topic by searching the forum using the term "flow-sensitive".

It's certainly a nice feature to have but Swift's type system is not currently designed to provide that feature.

1 Like