The Swift guard statement allows you to unwrap optionals to a new constant and do an early return if the assignment fails.
var someString:String? = "hello"
...
...
guard let newString = someString
else {
return
}
...
If I want to unwrap an optional and set it to a pre-defined non-optional variable, I've been first unwrapping to the new constant (newString) and then setting the non-optional variable after the guard statement like this:
var someString:String? = "hello"
var nonOptionalString:String = "bonjour"
...
...
guard let newString = someString
else {
return
}
nonOptionalString = newString
...
Is there a way to set a pre-defined, non-optional var within the condition of the guard statement without creating a new constant? Something like the following (which doesn't work)?
var someString:String? = "hello"
var nonOptionalString:String = "bonjour"
...
...
guard nonOptionalString = someString
else {
return
}
...
If something like this isn't possible, is there an underlying philosophy behind the Swift language design or technical reason as to why this doesn't exist?
I would just test for nil
and then force unwrap when I know it's not:
var someString: String? = "hello"
let nonOptionalString: String // note, you don't have to initialize this with some bogus value
guard someString != nil else { return }
nonOptionalString = someString!
Or if someString
was a parameter to some method or closure, you can unwrap in the guard
statement using the same variable name, simplifying life even more:
func foo(someString: String?) {
guard let someString = someString else { return }
// now I can just use local `someString`, which is not optional anymore
}
If you're desperate to unwrap and exit-if-nil
in a single statement, you could theoretically write a function to unwrap if it can or throw an error if it can't:
extension Optional {
enum OptionalError: Error {
case unwrapFailed
}
func unwrap<T>() throws -> T {
if self == nil { throw OptionalError.unwrapFailed }
return self as! T
}
}
Then you can do:
do {
firstNonOptional = try firstOptional.unwrap()
secondNonOptional = try secondOptional.unwrap()
thirdNonOptional = try thirdOptional.unwrap()
} catch {
return
}
I think that's horrible overkill, but if you're desperate to distill it down to one line per unwrap, that's one way to do it.