If not let - in Swift
Swift 2.0 (Xcode 7) and later have the new guard
statement, which sort of works like an "if not let" -- you can conditionally bind a variable in the remainder of the enclosing scope, keeping the "good path" in your code the least-indented.
guard let type = json.type else {
XCTFail("There is no type in the root element")
}
// do something with `type` here
The catch to this is that the else
clause of a guard
must exit that scope (because otherwise you'd fall into code after that clause, where the guarded variables, like type
above, are unbound). So it has to end with something like return
, break
, continue
or a function that is known to the compiler to never return (i.e. annotated @noreturn
, like abort()
... I don't recall offhand if that includes XCTFail
, but it should (file a bug if it's not).
For details, see Early Exit in The Swift Programming Language.
As for really-old stuff... There's no negated form of if-let in Swift 1.x. But since you're working with XCTest anyway, you can just make testing the optional part of an assertion expression:
XCTAssert(json.type != nil, "There is no type in the root element")
Here's how you do it:
if json.type == nil {
// fail
}
Another alternative I've used a few times:
switch json.type
{
case .None: // ...
case .Some(.Object): // ...
case .Some(.Array): // ...
case .Some(.Number): // ...
case .Some(.String): // ...
}
Since the ?
is actually Optional<T>
which is an enum on its own, defined as:
enum Optional<T> : Reflectable, NilLiteralConvertible
{
case None
case Some(T)
...
}